Re: Extracting property setter mechanism?
- From: Kirill Grouchnikov <kirillcool@yahoo.com>
- To: dev@trident.kenai.com
- Subject: Re: Extracting property setter mechanism?
- Date: Wed, 29 Jul 2009 00:03:44 -0700 (PDT)
- Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com; h=Message-ID:X-YMail-OSG:Received:X-Mailer:References:Date:From:Subject:To:In-Reply-To:MIME-Version:Content-Type; b=SzdSaLkSJEWQHLR781UR0BMi+Bjqj51pRMsA+J/1rUulCA3SfbJGB1MvZoyNdaeBuOge/dUCUp9htejYE5l5KTyMBgrCZ7LSbkUcu4LPP1uhTdqZgztn0aZ8RNDUuLb0LGzzliJXggnBX3+YomzLPmYL+uKdAtEcLIS0PKFweHI=;
Thanks for the valuable suggestion and the skeleton of the implementation.
Kirill
Kirill
From: Andres Almiray <aalmiray@yahoo.com>
To: dev@trident.kenai.com
Sent: Monday, July 27, 2009 12:15:24 PM
Subject: Re: Extracting property setter mechanism?
Thank you Kirill!
This will certainly help working with POJOs that expose properties in a non-standard way (or that do not expose properties at all!), same goes with Groovy's Maps, they have features that let them behave like a POJO.
Cheers,
Andres
-------------------------------------------
http://jroller.com/aalmiray
http://www.linkedin.com/in/aalmiray
--
What goes up, must come down. Ask any system administrator.
There are 10 types of people in the world: Those who understand binary, and those who don't.
To understand recursion, we must first understand recursion.
From: Kirill Grouchnikov <kirillcool@yahoo.com>
To: dev@trident.kenai.com
Sent: Sunday, July 26, 2009 9:22:39 PM
Subject: Re: Extracting property setter mechanism?
From: Andres Almiray <aalmiray@yahoo.com>
To: dev@trident.kenai.com
Sent: Thursday, July 16, 2009 10:10:51 AM
Subject: Re: Extracting property setter mechanism?
This will certainly help working with POJOs that expose properties in a non-standard way (or that do not expose properties at all!), same goes with Groovy's Maps, they have features that let them behave like a POJO.
Cheers,
Andres
-------------------------------------------
http://jroller.com/aalmiray
http://www.linkedin.com/in/aalmiray
--
What goes up, must come down. Ask any system administrator.
There are 10 types of people in the world: Those who understand binary, and those who don't.
To understand recursion, we must first understand recursion.
From: Kirill Grouchnikov <kirillcool@yahoo.com>
To: dev@trident.kenai.com
Sent: Sunday, July 26, 2009 9:22:39 PM
Subject: Re: Extracting property setter mechanism?
The latest drop of 1.1dev has the first support for fluent definition of complex property interpolations.
Most of the existing Timeline APIs to interpolate properties are now deprecated in favor of the new API and will be removed in the next major release.
The new API is Timeline.addPropertyToInterpolate(TimelinePropertyBuilder), where you get an instance of builder by calling the static Timeline.property API. See the different methods on the TimelinePropertyBuilder class that allow chained / fluent definition of complex property interpolations. As an example of usage (with custom property setter):
Timeline timeline = new Timeline(helloWorld);
timeline.addPropertyToInterpolate(Timeline.<Float> property("value")
.from(0.0f).to(1.0f).setWith(new PropertySetter<Float>() {
@Override
public void set(Object obj, String fieldName, Float value) {
SimpleDateFormat sdf = new SimpleDateFormat("mm:SSS");
float oldValue = helloWorld.value;
System.out.println(sdf.format(new Date()) + " : "
+ oldValue + " -> " + value);
helloWorld.value = value;
}
}));
timeline.play();
This example does not require you to expose the public setter method for the "value" property.
I've also generified some of the APIs in favor compile-time safety. You can see it in the example above - Timeline.<Float> property call. You can omit the <Float> - but if you pass inconsistent settings (from / to / property setter / property interpolator), it will only be caught at runtime. You can still get runtime exceptions - when you pass from/to values with no explicit property interpolator, and there is no registered interpolator for the values, but you still get more compile-time errors.
Let me know if this makes using Trident easier both in plain Java and in Groovy code. Also, this is my first attempt at fluent API, so any comments in that area (re readability) are welcome as well.
Thanks
Kirill
Most of the existing Timeline APIs to interpolate properties are now deprecated in favor of the new API and will be removed in the next major release.
The new API is Timeline.addPropertyToInterpolate(TimelinePropertyBuilder), where you get an instance of builder by calling the static Timeline.property API. See the different methods on the TimelinePropertyBuilder class that allow chained / fluent definition of complex property interpolations. As an example of usage (with custom property setter):
Timeline timeline = new Timeline(helloWorld);
timeline.addPropertyToInterpolate(Timeline.<Float> property("value")
.from(0.0f).to(1.0f).setWith(new PropertySetter<Float>() {
@Override
public void set(Object obj, String fieldName, Float value) {
SimpleDateFormat sdf = new SimpleDateFormat("mm:SSS");
float oldValue = helloWorld.value;
System.out.println(sdf.format(new Date()) + " : "
+ oldValue + " -> " + value);
helloWorld.value = value;
}
}));
timeline.play();
This example does not require you to expose the public setter method for the "value" property.
I've also generified some of the APIs in favor compile-time safety. You can see it in the example above - Timeline.<Float> property call. You can omit the <Float> - but if you pass inconsistent settings (from / to / property setter / property interpolator), it will only be caught at runtime. You can still get runtime exceptions - when you pass from/to values with no explicit property interpolator, and there is no registered interpolator for the values, but you still get more compile-time errors.
Let me know if this makes using Trident easier both in plain Java and in Groovy code. Also, this is my first attempt at fluent API, so any comments in that area (re readability) are welcome as well.
Thanks
Kirill
From: Andres Almiray <aalmiray@yahoo.com>
To: dev@trident.kenai.com
Sent: Thursday, July 16, 2009 10:10:51 AM
Subject: Re: Extracting property setter mechanism?
The PropertySetter interface is pretty much what I had in mind, however the downsize of API explosion worries me too. What if... addPropertyToInterpolate calls require a contextual object for additional features?
PropertySettings settings = new PropertySettings("background");
settings.setFrom(Color.BLUE);
settings.setTo(Color.RED);
settings.setTarget(mybean);
timeline.addPropertyToInterpolate(settings);
assuming the class is a POJO defined like
class PropertySettings {
private Object target; // may be null
private final String propertyName; // required
private Object from; // optional
private Object to; // must be optional because of KeyFrames
private PropertyInterpolator interpolator; // optional
private PropertySetter setter; // optional
private KeyFrames keyFrames; // optional
PropertySettings( String propertyName ) {
this.propertyName = propertyName
}
// getter & setters
}
or use the builder pattern + fluent interface design to favor immutability. There must be a way to validate that a PropertySettings instance has a value for 'to' or 'keyFrames'.
the following could be possible with the builder pattern + fluent interface design
addPropertyToInterpolate( property("background").on(target).from(Color.BLUE).to(Color.RED).build() )
property(String) being a statically imported factory method of the PropertySettingsBuilder class, build() should perform validation and return the real object or throw exceptions.
Thoughts?
From: Kirill Grouchnikov <kirillcool@yahoo.com>
To: dev@trident.kenai.com
Sent: Thursday, July 16, 2009 9:20:49 AM
Subject: Re: Extracting property setter mechanism?
From: "aalmiray@yahoo.com" <aalmiray@yahoo.com>
To: dev@trident.kenai.com
Sent: Wednesday, July 15, 2009 9:38:17 PM
Subject: Extracting property setter mechanism?
As pitched on twitter "@kirillcool any chance of encapsulating property
setters? I'm thinking of beans that do not follow the JavaBeans
convention or Maps".
Trident 1.0 works on the assumption that the target object must have a
setXyz() method for property xyz, otherwise it will fail. This works
fine between the boundaries of Java, but may be a bit strict for
Java.next, mainly Groovy. In Groovy objects may expose properties via
metaprogramming, meaning they may not have a setXyz() method but would
still respond to a property call, unfortunately
java.beans.PropertyDescriptor knows nothing of those properties. A
java.util.Map can also work as a bean replacement, there is even an
observable one, again its properties cannot be accessed via reflection
nor bean introspection.
It would be great if the property setting mechanism could be extracted
or made plugable, this would make integrating Trident with Java.next
languages a much easier task, however I'm aware that Trident was born
as a Java library, that it should stay between the regular Java
boundaries, that extracting the property setting mechanism may impose a
performance hit on Java applications when previously there was none, so
this is more of a wish.
Thanks for listening.
- Andres
PropertySettings settings = new PropertySettings("background");
settings.setFrom(Color.BLUE);
settings.setTo(Color.RED);
settings.setTarget(mybean);
timeline.addPropertyToInterpolate(settings);
assuming the class is a POJO defined like
class PropertySettings {
private Object target; // may be null
private final String propertyName; // required
private Object from; // optional
private Object to; // must be optional because of KeyFrames
private PropertyInterpolator interpolator; // optional
private PropertySetter setter; // optional
private KeyFrames keyFrames; // optional
PropertySettings( String propertyName ) {
this.propertyName = propertyName
}
// getter & setters
}
or use the builder pattern + fluent interface design to favor immutability. There must be a way to validate that a PropertySettings instance has a value for 'to' or 'keyFrames'.
the following could be possible with the builder pattern + fluent interface design
addPropertyToInterpolate( property("background").on(target).from(Color.BLUE).to(Color.RED).build() )
property(String) being a statically imported factory method of the PropertySettingsBuilder class, build() should perform validation and return the real object or throw exceptions.
Thoughts?
From: Kirill Grouchnikov <kirillcool@yahoo.com>
To: dev@trident.kenai.com
Sent: Thursday, July 16, 2009 9:20:49 AM
Subject: Re: Extracting property setter mechanism?
Hi Andres
This idea has already been suggested by Remy, and i have been thinking about it for a while. First, allow me to copy-paste the last paragraph from [1]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
The second method can be used by applications that do not wish to add public setters for all the fields that participate in the timelines. Instead of using the
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
The documentation is talking about a custom application callback registered with a timeline.
Now, let me explore how the existing property setter can be extended. Starting with the most basic addPropertyToInterpolate(String fieldName, Object from, Object to) that eventually looks up the matching setter via the PropertyDescriptor - how can this be extended to handle arbitrary setter / update? I would imagine something like
interface PropertySetter {
public void set(Object obj, String fieldName, Object value);
}
and the matching API - addPropertyToInterpolate(String fieldName, Object from, Object to, PropertySetter setter). Then, i can have the bean-based implementation of PropertySetter, and you can create your own implementations of that interface.
There is a downside to this - all 4 addPropertyToInterpolate and all 3 addPropertyToInterpolateTo will need to have the matching counterpart, effectively doubling the API size.
Any thoughts?
Thanks
Kirill
[1] http://kenai.com/projects/trident/pages/TimelineLifecycle
This idea has already been suggested by Remy, and i have been thinking about it for a while. First, allow me to copy-paste the last paragraph from [1]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
The second method can be used by applications that do not wish to add public setters for all the fields that participate in the timelines. Instead of using the
Timeline.addPropertyToInterpolate() to interpolate the fields via public setters, a timeline callback that interpolates the fields directly in the onTimelinePulse() can be used.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
The documentation is talking about a custom application callback registered with a timeline.
Now, let me explore how the existing property setter can be extended. Starting with the most basic addPropertyToInterpolate(String fieldName, Object from, Object to) that eventually looks up the matching setter via the PropertyDescriptor - how can this be extended to handle arbitrary setter / update? I would imagine something like
interface PropertySetter {
public void set(Object obj, String fieldName, Object value);
}
and the matching API - addPropertyToInterpolate(String fieldName, Object from, Object to, PropertySetter setter). Then, i can have the bean-based implementation of PropertySetter, and you can create your own implementations of that interface.
There is a downside to this - all 4 addPropertyToInterpolate and all 3 addPropertyToInterpolateTo will need to have the matching counterpart, effectively doubling the API size.
Any thoughts?
Thanks
Kirill
[1] http://kenai.com/projects/trident/pages/TimelineLifecycle
From: "aalmiray@yahoo.com" <aalmiray@yahoo.com>
To: dev@trident.kenai.com
Sent: Wednesday, July 15, 2009 9:38:17 PM
Subject: Extracting property setter mechanism?
As pitched on twitter "@kirillcool any chance of encapsulating property
setters? I'm thinking of beans that do not follow the JavaBeans
convention or Maps".
Trident 1.0 works on the assumption that the target object must have a
setXyz() method for property xyz, otherwise it will fail. This works
fine between the boundaries of Java, but may be a bit strict for
Java.next, mainly Groovy. In Groovy objects may expose properties via
metaprogramming, meaning they may not have a setXyz() method but would
still respond to a property call, unfortunately
java.beans.PropertyDescriptor knows nothing of those properties. A
java.util.Map can also work as a bean replacement, there is even an
observable one, again its properties cannot be accessed via reflection
nor bean introspection.
It would be great if the property setting mechanism could be extracted
or made plugable, this would make integrating Trident with Java.next
languages a much easier task, however I'm aware that Trident was born
as a Java library, that it should stay between the regular Java
boundaries, that extracting the property setting mechanism may impose a
performance hit on Java applications when previously there was none, so
this is more of a wish.
Thanks for listening.
- Andres
| aalmiray | 07/16/2009 | |
| Kirill Grouchnikov | 07/16/2009 | |
| Andres Almiray | 07/16/2009 | |
| Kirill Grouchnikov | 07/17/2009 | |
| Kirill Grouchnikov | 07/27/2009 | |
| Andres Almiray | 07/27/2009 | |
|
Re: Extracting property setter mechanism? |
Kirill Grouchnikov | 07/29/2009 |





