ideas and wishlist for 0.8

2 views
Skip to first unread message

Johan Rydberg

unread,
Apr 28, 2010, 2:43:18 AM4/28/10
to GWT Pectin
Here's a few notes on what i like to see in pectin. Hopefully
my time will allow me to contribute one or several of these;

1. nested beans, at least the simple "a.b.c" case.

2. while-you-type validation

3. use clientbundle to get rid of external css files,
or let the user specify what class-name should be
used for watermarking and marking a control as invalid

my top priority is (1) right now.

Johan Rydberg

unread,
Apr 28, 2010, 5:05:17 AM4/28/10
to gwt-pecti...@googlegroups.com
On 4/28/10 8:43 AM, Johan Rydberg wrote:
> Here's a few notes on what i like to see in pectin. Hopefully
> my time will allow me to contribute one or several of these;
>
> 1. nested beans, at least the simple "a.b.c" case.
(This is mostly notes to myself, on how things could be done:)

I've been looking at JFace's properties API [1] as a model. It has
a chaining-call API which is quite similar to the one gwt-pectin
already has.

Adopting those ideas to gwt-pectin shouldn't be too hard i think.

Let beans implement a HasPropertyChangeHandlers interface.
That interface will act as a marker interface for a generator that
implements property descriptions for the bean.

The bean itself will do the whole java.beans.PropertyChange thing.

My hopes is that the binding could end up looking something like this;


fieldOfType(String.class).boundTo(BeanProperties.observe(foo).value("a").value("b"));

The two value calls can of course be combined into a .value("a.b") for ease.

BeanProperties.observe take a HasPropertyChangeHandlers<T> (T is the
bean-class)
or a ValueModel<T extends HasPropertyChangeHandlers<T>> and will return
a builder that is used to find properties.

[1]
http://fire-change-event.blogspot.com/2009/02/introducing-properties-api.html

Johan Rydberg

unread,
Apr 28, 2010, 10:11:02 AM4/28/10
to gwt-pecti...@googlegroups.com

>
>
> fieldOfType(String.class).boundTo(BeanProperties.observe(foo).value("a").value("b"));
>
>
Here is a proof of concept;

http://ginandtonique.org/public/DataTest.tar.gz

My generics-fu isn't top notch so there's a few casts
here and there.

Haven't tried it with gwt-pectin just yet, but the
simple test-case works. And it's all based on ValueModel
so it _should_ work with pectin! :)


Andrew

unread,
Apr 28, 2010, 8:07:58 PM4/28/10
to GWT Pectin
Thanks for that. It's probably worth raising issues for these too.

On Apr 28, 4:43 pm, Johan Rydberg <johan.rydb...@edgeware.tv> wrote:
> Here's a few notes on what i like to see in pectin. Hopefully
> my time will allow me to contribute one or several of these;
>
> 1. nested beans, at least the simple "a.b.c" case.

Cool. Thanks for looking into this.

> 2. while-you-type validation

I've had a feature like this in a previous Swing version of pectin
(i.e. called validation triggers). In that case I used interceptors
on the bindings so plugins can intercept value changes. It's
important to do it in the binding as just doing the validation on a
value change means you can't distinguish between programatic updates
or user updates (i.e. you don't want you're validation firing when you
set an empty bean instance on your form).

One of the things in the Apple documentation you sent was the notion
that validator could choose to replace the value with another, which
would be another nice thing to look at, although that's more complex
than just validate as you type (as the binding would have to push the
replacement value back into the widget and the validator/result
collector interfaces would need to change).

> 3. use clientbundle to get rid of external css files,
> or let the user specify what class-name should be
> used for watermarking and marking a control as invalid

This would be good too. For validation you can sort of hack this now
(in an ugly sort of way). Calling
`ValidationStyles.defaultInstance().registerStyleName(Severity,
String)` lets you change the class name. But you'd have to do it on
`ValidationStyles.defaultDependentStyleNameInstance()` too which
sucks. There's nothing of the sort for watermarks at this point in
time. I think as a minimum it would be worth looking at doing
something like `ValidationPlugin.defaults().registerStyle(Severity,
String)` and similar for the other plugins.

Another feature I'd like to add is support for un-ordered lists
(there's already a bug related to this http://code.google.com/p/gwt-pectin/issues/detail?id=14).
I'm not really sure how to name it,
`unorderedListOfType(String.class)` is really long so I'm considering
`bagOfType(String.class)`. This will introducing another model type
so that's going to be a fair amount of work (especially since it also
impacts the validators etc).

Andrew

unread,
Apr 28, 2010, 9:39:27 PM4/28/10
to GWT Pectin
Thanks for that. I've had a quick look, sorry for the length of the
post.. (c:

On Apr 29, 12:11 am, Johan Rydberg <johan.rydb...@edgeware.tv> wrote:
> > fieldOfType(String.class).boundTo(BeanProperties.observe(foo).value("a").value("b"));
>
> Here is a proof of concept;
>
> http://ginandtonique.org/public/DataTest.tar.gz
>
Were you thinking of supporting POJOs too? i.e. things like DTOs that
don't implement FiresPropertyChangeEvents? They're something I use a
lot, in fact I rarely (i.e. never) use property change events any more
since they're keyed by string and not type safe (unlike
ValueChangeEvents). Even though I don't use them, clearly other
people do so it' probably worth supporting both (c:

Also, were you thinking of automating any of the PropertyDescription
stuff? It's a fair whack of code to write for every bean.

My initial thoughts when thinking about extending the current
providers would be that I'd annotate bean properties that were to be
exposed to pectin (e.g. something like @BeanPropertySource) and let
the deferred bindings crunch out the boiler plate. The deferred
binding can also guarentee the property path is valid both in terms of
name and type when the value model is created. This has always been
important since it means that a unit test that simply instantiates the
form proves the property paths are all ok.
i.e. `fieldOfType(String.class).boundTo(beanProvider, "a.b.c")` should
barf if the properties a, b or c aren't defined and if c isn't an
instance of String.

The other option which I'd been pondering is code generation. I
seriously considered early on but since there's no unified build
system I decided not to (I would have been easy enough to write a
Gradle plugin, but pectin would be useless out of the box unless I
supported ant and maven too). There was mention of adding a code
generation hook in GWT so that would change the game a bit. That way
you could build type safe bean property keys and do stuff like
`boundTo(ValueModel<T>, TProperties.a().b().c())` or some such.

A lot of this is very similar to google's ValueStore/ValueBox design
(properties, types, keys, paths etc) so I'm also keen to see what
comes out of that. At the end of the discussion at
https://wave.google.com/wave/?pli=1#restored:wave:googlewave.com!w%252B3IMMyKcVB
Ray Ryan made the comment:

> The RequestFactory is wokring with much more beanie
> things. And my hope is that the data binding stuff will
> be independent of the RequestFactory implementation(s),
> and work with any old bean.

I haven't seen any further info though.

Johan Rydberg

unread,
Apr 29, 2010, 2:46:35 AM4/29/10
to gwt-pecti...@googlegroups.com
On 4/29/10 3:39 AM, Andrew wrote:
> Thanks for that. I've had a quick look, sorry for the length of the
> post.. (c:
>
No worries. It's just a proof-of-concept. Just don't expect that I had
put too much thought into the whole thing! :)
> On Apr 29, 12:11 am, Johan Rydberg<johan.rydb...@edgeware.tv> wrote:
>
>>> fieldOfType(String.class).boundTo(BeanProperties.observe(foo).value("a").value("b"));
>>>
>> Here is a proof of concept;
>>
>> http://ginandtonique.org/public/DataTest.tar.gz
>>
>>
> Were you thinking of supporting POJOs too? i.e. things like DTOs that
> don't implement FiresPropertyChangeEvents? They're something I use a
> lot, in fact I rarely (i.e. never) use property change events any more
> since they're keyed by string and not type safe (unlike
> ValueChangeEvents). Even though I don't use them, clearly other
> people do so it' probably worth supporting both (c:
>
It wouldn't be too hard to support POJOs. You just need a way to get
data in and out of the POJO (ie
generate PropertyDescriptions for it somehow)
> Also, were you thinking of automating any of the PropertyDescription
> stuff? It's a fair whack of code to write for every bean.
>
Of course. The idea is to have a generator that searches for all beans
that have a marker interface
(maybe FiresPropertyChangeEvents, or some other for POJOs) and generate
the descriptions for
those classes.
> My initial thoughts when thinking about extending the current
> providers would be that I'd annotate bean properties that were to be
> exposed to pectin (e.g. something like @BeanPropertySource) and let
> the deferred bindings crunch out the boiler plate.
More in detail, how would you do that? Will the generated boilerplate
also fire events?

I would love to get rid of the boilerplate in the bean, but I can't seem
to figure out how to.
You don't want so subclass the bean and add the mechanism there, because
the bean can
originate from anywhere (all my beans will come from server-side).

But for me the boilerplate won't be that hard to control, since I will
generate all my bean
classes from my server-side python model classes.

> The deferred
> binding can also guarentee the property path is valid both in terms of
> name and type when the value model is created. This has always been
> important since it means that a unit test that simply instantiates the
> form proves the property paths are all ok.
> i.e. `fieldOfType(String.class).boundTo(beanProvider, "a.b.c")` should
> barf if the properties a, b or c aren't defined and if c isn't an
> instance of String.
>
That would be really nice. If you figure out a way to do that I would
be really glad! ;)

Andrew Pietsch

unread,
Apr 29, 2010, 8:29:34 PM4/29/10
to gwt-pecti...@googlegroups.com
Howdy,

My initial thoughts when thinking about extending the current
providers would be that I'd annotate bean properties that were to be
exposed to pectin (e.g. something like @BeanPropertySource) and let
the deferred bindings crunch out the boiler plate.
More in detail, how would you do that?   Will the generated boilerplate also fire events?

I would love to get rid of the boilerplate in the bean, but I can't seem to figure out how to.
You don't want so subclass the bean and add the mechanism there, because the bean can
originate from anywhere (all my beans will come from server-side).

Yeah, nah I meant the bean provider template code and not the beans themselves (i.e. code like the PropertyDescriptors).  I wish there was a solution for beans, I've used property change events in Swing for years and they were always a pain to write.  Mostly I just used Intellij templates to ease the pain.  The only solution I know of is code generation.

<ignore>
Now days if I need a simple observable property I just use a ValueHolder behind the scenes. e.g.

public class MyObjectWithAnObservableProperty {
  private ValueHolder<String> nameModel = new ValueHolder<String>();
  // for those who want bean accessors
  public void setName(String name) {nameHolder.setValue(name);}
  public void getName() {return nameHolder.getValue();}
  // for those who want events.
  public ValueModel<String> getNameModel() {return nameModel;}
}
 
By exposing the ValueModel I can then use it in forms or conditions or widget bindings etc.  I don't do this for classes that go across the wire though (or for an object graph), I just use POJOs/DTOs for that and use the providers to munge them into the value model I need.
</ignore>

But for me the boilerplate won't be that hard to control, since I will generate all my bean
classes from my server-side python model classes.

That's pretty nice.  In that case could you create specialised value model factories for your beans?  I.e. perhaps something like FooFactoryThingy.observe(foo).a().bar()?  or Observables.observe(foo, FooProperties.A.BAR)?   That way you'd get compile time type safety and code completion etc which would be pretty sweet.  Something like this (especially if it worked off regular beans) would be very cool indeed.


The deferred
binding can also guarentee the property path is valid both in terms of
name and type when the value model is created.  This has always been
important since it means that a unit test that simply instantiates the
form proves the property paths are all ok.
i.e. `fieldOfType(String.class).boundTo(beanProvider, "a.b.c")` should
barf if the properties a, b or c aren't defined and if c isn't an
instance of String.
 
That would be really nice.  If you figure out a way to do that I would be really glad! ;)

The current providers do this already since they create big if/else structures for each bean so it know's if you've asked for a property that doesn't exist, or that has the wrong type etc.  I think (fingers crossed) I can extend this to basic property paths (but no support for lists or maps etc like OGNL).

I was thinking of using an annotation to mark properties that the provider should expose, e.g.

public class Person {
   private String name;
   private Address address;

   public String getName() {..}
   public void setName(String name) {..}

   // let pectin know it should build nested property mappings.
   @NestedBean
   public Address getAddress() {..}
   public void getAddress(Address address) {..}
}

Then when the deferred binding is building the list of properties I'm hoping we can traverse the address bean and generate the neccessary methods for property paths like "address.postCode" etc.  It's a little more complicated than that how ever as I'll probably have to use something like a BeanModelProviders behind the scenes... but they're generated by deffered binding.. so it will need to be different.  Anyway, that's why I haven't done it yet... (c:

I'm not really sure at this point what approach to take, I mean is it worth implementing `fieldOfType(String.class).boundTo(beanProvider, "a.b.c")` when with code generation we could possibly do something like `fieldOfType(String.class).boundTo(beanHolder, BeanProperties.A.B.C)` (where beanHolder is a regular value model, the BeanProperties is autogenerated and A.B.C etc returns a PropertyDescription like thingy?).  And/or should we wait to see what becomes of http://code.google.com/p/google-web-toolkit/source/browse/trunk/bikeshed/src/com/google/gwt/valuestore/shared/

What do you think?



Andrew

unread,
May 17, 2010, 11:47:44 PM5/17/10
to GWT Pectin
I've had a go at the boundTo(provider, "a.b.c") approach using a
@NestedBean annotation and have got the basics working (no auto-commit
version yet). I haven't checked it in yet as it's quite a bit
different from the other and I'll probably have to deprecate them. I
see no problem in putting this in the next release once I decide what
to do with the older providers.

Cheers
> wait to see what becomes ofhttp://code.google.com/p/google-web-toolkit/source/browse/trunk/bikes...
>
> What do you think?

Johan Rydberg

unread,
May 18, 2010, 5:32:44 AM5/18/10
to gwt-pecti...@googlegroups.com
On 5/18/10 5:47 AM, Andrew wrote:
> I've had a go at the boundTo(provider, "a.b.c") approach using a
> @NestedBean annotation and have got the basics working (no auto-commit
> version yet). I haven't checked it in yet as it's quite a bit
> different from the other and I'll probably have to deprecate them. I
> see no problem in putting this in the next release once I decide what
> to do with the older providers.
>
That's great Andrew. I guess this doesn't have support for notifying
the bindings when a property changes?

Andrew

unread,
May 18, 2010, 10:22:35 PM5/18/10
to GWT Pectin
It doesn't at this point, but I don't think it would be too hard to
retrofit in. If I add a an
BeanPropertyValueModel.onSourceBeanChanged() method you could extend
the new BeanModelProvider, override the factory methods (that create
the BeanPropertyValueModels) to return a subclass that manages
listener registrations using the above method. There might be a
better way with less subclassing but that would probably suffice as a
first pass to see how it works. If I were to add this to directly to
Pectin I'd need to introduce the various property change interfaces
you're using, are the from a third party library or have you rolled
your own?

Andrew

unread,
Jun 2, 2010, 7:27:22 PM6/2/10
to GWT Pectin
Nested bean support has now been checked into svn if any are
interested. The release notes contain the basic info:
http://code.google.com/p/gwt-pectin/wiki/ReleaseNotes

Johan Rydberg

unread,
Jun 3, 2010, 9:42:48 AM6/3/10
to gwt-pecti...@googlegroups.com
On 6/3/10 1:27 AM, Andrew wrote:
> Nested bean support has now been checked into svn if any are
> interested. The release notes contain the basic info:
> http://code.google.com/p/gwt-pectin/wiki/ReleaseNotes
>
Great work Andrew!

Btw, the gwtx package has those "bounded properties" classes that I used
in my experiment.
PropertyListener and friends. Maybe it's better to depend on a package
like that than to
roll your own.


Reply all
Reply to author
Forward
0 new messages