IntelliJ does a good job of locating String usages of property names when you refactor a property name, which is nice. Not sure if Eclipse/Netbeans do this also.

If you use CompoundPropertyModels then wouldn't refactoring your business objects will still silently break code?

It seems that ideally you'd just reference a property by its name, and continue using things like CompoundPropertyModel, PropertyResolver, etc. which accept string representations of properties. Using a code generation tool + generation gap pattern is a good way to accomplish this for now, have the code generation template generate String constants for all your property names in the generated entity superclass java file.

All that said, this is a pretty nifty trick. I wonder how much it will actually benefit developers, though.

-Sam



On Feb 26, 2008, at 10:43 AM, Igor Vaynberg wrote:

not really sure. but this is how it would work.

proxies in cglib take handlers. so you would do:

String key=modelclass.getname();
Class proxy=cache.get(key);
if (proxy==null) {
   proxy=cglib.createproxy(modelclass);
   cache.put(key,proxy);
}
proxyhandler handler=new proxyhandler(this);
Object instance=proxy.getconstructor(handler.class).newinstance (handler);

so we reuse the generated proxy class for all instances of the given
model class, and use a fresh handler to intercept all calls to proxy
and build the expression.

-igor



On Tue, Feb 26, 2008 at 10:36 AM, James Carman
<[EMAIL PROTECTED]> wrote:
So, you would cache the generated class (based on the type passed in)
 and then have it generate a new object each time.  Then, cast that
 object to Factory and set its callbacks?



 On 2/26/08, Igor Vaynberg <[EMAIL PROTECTED]> wrote:
we can cache the created proxy class and simply give each instance a
 new handler...


 -igor



 On Tue, Feb 26, 2008 at 10:26 AM, James Carman
 <[EMAIL PROTECTED]> wrote:
Have you tried this out using load testing?  You are creating a new
 class every time you create a model.  Have you run out of permgen
 space?



 On 2/26/08, Sebastiaan van Erk <[EMAIL PROTECTED]> wrote:
Well, there's a problem with normal PropertyModels (or
 CompoundPropertyModels).

 For example, if you have the following textfield:

 TextField tf = new TextField("name", new PropertyModel(customer,
 "customerName"));

Then a refactor of the customerName property (and the getCustomerName() method) in an IDE such as Eclipse or NetBeans will *silently* break the
 above code, which you will discover only at runtime...

 The proxy based approach solves exactly this problem.

 Regards,

Sebastiaan




 atul singh wrote:
I feel this approach does NOT solve a problem.....Its just an alternative ..

On Tue, Feb 26, 2008 at 4:48 PM, Matej Knopp <[EMAIL PROTECTED]> wrote:

We've reworked the implementation a bit,it works like this:


SafePropertyModel<Person> p = new SafePropertyModel<Person> (new Person());
TextField field = new TextField("name", p.bind(p.property
().getFirstName()));

It's attached to the JIRA issue:
https://issues.apache.org/jira/browse/WICKET-1327

-Matej


On Tue, Feb 26, 2008 at 11:32 AM, Sebastiaan van Erk
<[EMAIL PROTECTED]> wrote:
Matej Knopp wrote:
Hi,

On Tue, Feb 26, 2008 at 11:13 AM, Sebastiaan van Erk
<[EMAIL PROTECTED]> wrote:
Matej Knopp wrote:
model.getFirstName() can't really return IModel, if
Customer.getFirstName() returns string.

Anyway, I like the idea, but I don't like the syntax. instead of
one
line [add(new TextField("id", model).setRequred(true)) ] you have
now
three separate lines.

So I was thinking of something more like

SafePropertyModel<Customer> model = new
SafePropertyModel<Customer>(customer);

add(new TextField("tf", model.bind(model.proxy
().getCustomerName()
)).setRequired(true));

This way you can have it one one line.

-Matej

 So proxy() returns a Customer proxy?

And model.bind() takes an Object argument (considering we don't
know in
 advance what type getCustomerName() returns)... What about
primitive
 types? Overload bind() for those as well?
Well, the return object is not important at all. What is important is the getCustomerName() call. That marks somewhere in the model that
last accessed property was called "customerName". and then
immediately
after this model.bind takes this information.

OK, that's what I described. :-) And I was being stupid with respect to the overloading. If bind takes an object as argument, then overloading
 will not be necessary due to autoboxing. :-)


And the call to getCustomerName() has the side effect of setting a
model
object somewhere (e.g., in an instance field of model) which
 model.bind() can subsequently return?
Model bind will return a model (variation of propertymodel probably). It will take the information that getCustomerName call on proxy
provided.

Ok, so the proxy remembers which getter was called last, and you use
 that to construct the model in bind(). Of course.


Very interesting. I don't like the proxy() method name though. If
you
call it something like property() it will look more like you're
binding
 to a property of Customer:
Well, the naming can certainly be improved. I'm not sure about
"property()" though. Well, we can discuss this more anyway.
 model.bind(model.property().getCustomerName())

Neither am I. :-) For one, it's quite long. But on the other hand, you do bind to a model property, and so it reads ok. I think that proxies should be "invisible" for general users, so they shouldn't have to understand the magic going on here, nor that proxies are involved.


 VERY neat idea though... :-)
Thanks.

What I really like about this solution is that it can be implemented completely separately from wicket-core, so you can just put it in it's
 own project. :-)

 Regards,
 Sebastiaan



-Matej
 Regards,
 Sebastiaan




On Fri, Feb 8, 2008 at 6:17 PM, Johan Compagner <
[EMAIL PROTECTED]> wrote:
don't worry about creating the models
 That will happen anyway in 1.3 (that needs to be done for
example to get the
 right object especially when we generify stuff)

 see CompoundPropertyModel.wrapOnInheritance()

 joan





On Feb 8, 2008 5:41 PM, Scott Swank <[EMAIL PROTECTED]>
wrote:

Interesting.  So

  model.getFirstName()

would return a PropetyModel based on the results of
proxy.eval()?  If
I understand you correctly that creates many models (one per
component) instead of reusing a single model, but that may
well not be
the end of the world.  Or does getFirstName() return a
CompoundModel
that is properly bound this this component? Intriguing none
the less.
I hadn't considered this option, but I'm going to play with
it a bit.
 I rather like that direction.


On Feb 8, 2008 8:29 AM, Johan Compagner <[EMAIL PROTECTED]>
wrote:
i try to look at this this weekend, but i have a quick
question
I find it a bit verbose can't it be a bit shorter like this
(just an
example)

SharedPropertyModel<Customer> model = new
SharedPropertyModel<Customer>(customer);
this.setModel(model);

FormComponent firstName = new
CustomerNameField("firstName",
model.getFirstName()).setRequired(true);
add(firstName);

where getFirstName() returns the model

johan





On Feb 6, 2008 6:57 PM, Scott Swank <[EMAIL PROTECTED]>
wrote:

One of our more clever developers created a
CompoundPropertyModel that
uses a cglib proxy to strongly bind the mutators to the
model.  It
looks like this:

               SharedPropertyModel<Customer> model = new
SharedPropertyModel<Customer>(customer);
               this.setModel(model);

               FormComponent firstName = new
CustomerNameField("firstName").setRequired(true);
model.bind(firstName).to().getFirstName ();
               add(firstName);

               FormComponent lastName = new
CustomerNameField("lastName").setRequired(true);
               model.bind(lastName).to().getLastName();
               add(lastName);

               FormComponent addr1 = new
AddressField("address1").setRequired(true);
               model.bind
(addr1).to().getAddress().getAddress1();
               add(addr1);

               FormComponent addr2 = new
AddressField("address2");
               model.bind
(addr2).to().getAddress().getAddress2();
               add(addr2);

               FormComponent city = new
CityField("city");
               model.bind
(city).to().getAddress().getCity();
               add(city);

We're happy to share if folk like this approach.  N.B.
that the .to()
call is for readability rather than out of any necessity.

Cheers,
Scott

--
Scott Swank
reformed mathematician



---------------------------------------------------------------- -----
To unsubscribe, e-mail:
[EMAIL PROTECTED]
For additional commands, e-mail:
[EMAIL PROTECTED]






--
 Scott Swank
reformed mathematician


---------------------------------------------------------------- -----
To unsubscribe, e-mail: users- [EMAIL PROTECTED] For additional commands, e-mail: users- [EMAIL PROTECTED]













--
Resizable and reorderable grid components.
http://www.inmethod.com

---------------------------------------------------------------- -----
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]






------------------------------------------------------------------- --
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]



-------------------------------------------------------------------- -
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to