You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@pivot.apache.org by Greg Brown <gb...@vmware.com> on 2009/06/08 20:17:29 UTC

[DISCUSS] WTKX binding

Hi all,

I've recently been working on a "real-world" app using Pivot, and I've  
run into a situation where I'd like to use WTKX binding, but I can't.  
I want to create a FileBrowserSheet class that extends Sheet and loads  
its contents from a WTKX file.

In order for a Sheet subclass to take advantage of binding to process  
the WTKX, Sheet would somehow need to extend Bindable. However,  
Sheet's root base class is Component, which currently extends Object.  
We could conceivably make Component extend Bindable; however, we  
decided a while back for a variety of reasons that WTK classes should  
not be dependent on WTKX, and I would prefer to stick with that  
decision.

I think it will be fairly common for developers to want to bind to  
application-specific Window subclasses; for example, LoginDialog,  
FileOpenDialog, ContactInfoSheet, etc. I also think that any non- 
trivial application will want to define a main application window  
class rather than embedding the UI details in the application itself.  
For example, I might define MyApplication that implements Application,  
and MyApplicationWindow that extends Window. MyApplication would  
simply serve as the entry point into the application, playing the same  
role as the main() method in a typical Java application. We wouldn't  
be able to use binding in any of these use cases.

I see two options for resolving this issue:

1) Continue to support Bindable, but move it out of pivot.wtkx,  
possibly to pivot.util or pivot.wtk. As a result of this move, we  
would lose support for @Load, since it depends on WTKXSerializer.  
However, we could retain support for @Bind.

2) Eliminate Bindable altogether. This seems drastic, especially since  
the annotations do tend to clean up the code a bit. However, there is  
a lot of code behind that support that needs to be maintained, and I'm  
not sure it is justified.

I'm leaning pretty strongly towards #2. This is what the code in my  
FileBrowserSheet constructor looks like without binding (I'm assuming  
the existence of a template parameter in WTKXSerializer - that can be  
discussed as another topic, if necessary):

Resources resources = new Resources(this);
setTitle(resources.getString("title"));

WTKXSerializer<Component> wtkxSerializer = new  
WTKXSerializer<Component>(resources);
setContent(wtkxSerializer.readObject(this, "file_browser.wtkx"));

folderTreeView = wtkxSerializer.get("folderTreeView");
okButton = wtkxSerializer.get("okButton");
cancelButton = wtkxSerializer.get("cancelButton");

With binding, the final three lines would be replaced with bind(),  
which is very concise. However, the above code is still pretty  
readable. Yes, we have to manually assign the member variables, but is  
that really that much of a burden on developers? Is the simplification  
offered by the bind() method enough to justify the additional code  
maintenance of the Bindable class and the bind processor?

The bind processor is what we use to rewrite the Bindable class files  
at compile time so they can run in an untrusted applet. It is worth  
noting that the processor currently relies on undocumented features of  
the javac compiler. When binding seemed like it might be more  
generally useful, I thought that this would be an OK risk to take.  
However, now I don't think so.

I'm going to suggest that we eliminate the Bindable class and revert  
to the previous way of loading and processing WTKX. I've made some  
minor API additions that simplify the use of WTKXSerializer directly.  
pivot.util.Resources now takes a base object or class, so you can write:

Resources resources = new Resources(this);

If your class is named com.foo.MyClass, it will automatically load  
com.foo.MyClass.json.

I also added a readObject() overload to WTKXSerializer that takes an  
object and a resource name. Now, instead of this:

wtkxSerializer.readObject(getClass().getResource("foo.wtkx"));

you can write this:

wtkxSerializer.readObject(this, "foo.wtkx");

Again, minor changes, but they make the code that much more readable.

I understand that @Bind is pretty convenient, but it can't currently  
be used in what I suspect will be a common use case, and, in my  
opinion, adapting it such that it can be used for this purpose makes  
it less compelling (especially since it requires undocumented features  
of the compiler). Please let me know what you think.

Thanks,
Greg


Re: [DISCUSS] WTKX binding

Posted by Greg Brown <gk...@mac.com>.
> Unfortunately in Java, you can't invoke a specific subclass version of
> an overridden method.

I believe you can do this using reflection. I'll prototype it and  
verify.


Re: [DISCUSS] WTKX binding

Posted by Greg Brown <gk...@mac.com>.
Forgot that .java attachments don't go through. Here it is:

package pivot.wtkx.test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class BindingPrototype {
     public static void main(String[] args) {
         C c = new C();

         Class<?> type = c.getClass();
         while (type != Object.class) {
             try {
                 Method __bindMethod =  
type.getDeclaredMethod("__bind", new Class<?>[] {type});

                 try {
                     __bindMethod.invoke(null, new Object[] {c});
                 } catch(IllegalAccessException exception) {
                     throw new RuntimeException(exception);
                 } catch(InvocationTargetException exception) {
                     throw new RuntimeException(exception);
                 }
             } catch(NoSuchMethodException exception) {
                 // No-op
             }

             type = type.getSuperclass();
         }
     }
}

class A {
     public static void __bind(A a) {
         System.out.println("A");
     }
}

class B extends A {
}

class C extends B {
     public static void __bind(C c) {
         System.out.println("C");
     }
}


On Jun 9, 2009, at 1:00 PM, Greg Brown wrote:

> You are correct - it doesn't work. The Javadoc for Method#invoke()  
> says this:
>
> "If the underlying method is an instance method, it is invoked using  
> dynamic method lookup as documented in The Java Language  
> Specification, Second Edition, section 15.12.4.4; in particular,  
> overriding based on the runtime type of the target object will occur."
>
> However, maybe it could be static:
>
> public static __bind(T t, WTKXSerializer serializer) { ... }
>
> where T is the type of the class that contains an @Bind annotation  
> (not a generic - the actual type). It could be Object, but there's  
> no need for it to be since we know what type it is. Since it is a  
> static method of the class, it will have access to the class's  
> internal variables, but won't be overridden by a subclass.
>
>
> On Jun 9, 2009, at 12:33 PM, Noel Grandin wrote:
>
>> Unfortunately in Java, you can't invoke a specific subclass version  
>> of
>> an overridden method.
>>
>> That means that either
>> (a) you have to trust that each method correctly invokes super.__bind
>> (b) we need a more complex scheme.
>>
>> Something like having each class X define a method
>> public void __bind(X myself, WTKXSerializer serializer)
>> And then WTKXSerializer#bind() could walk up the class hierarchy,
>> and use reflection to find the __bind methods and invoke them.
>>
>> But maybe someone can come up with a scheme that involves less magic?
>> (I like reflection, but it's best used in small doses).
>>
>>
>> On Tue, Jun 9, 2009 at 17:14, Greg Brown<gk...@mac.com> wrote:
>>> I think this will actually work, and won't require too many  
>>> changes. The
>>> bind processor can add the Bindable interface to every class that  
>>> uses an
>>> @Bind annotation. The interface would contain a single method:
>>>
>>> public void __bind(WTKXSerializer serializer);
>>>
>>> WTKXSerializer#bind() would check to see if the bound object  
>>> implemented
>>> Bindable; if so, it would walk up the object's class hierarchy  
>>> looking for
>>> subclasses that implement Bindable. When found, it would invoke  
>>> the specific
>>> __bind() method defined by the subclass.
>>>
>>> Sound right?
>>>
>


Re: [DISCUSS] WTKX binding

Posted by Greg Brown <gk...@mac.com>.
I just verified that the static approach will work. See attached.
-G


Re: [DISCUSS] WTKX binding

Posted by Greg Brown <gk...@mac.com>.
You are correct - it doesn't work. The Javadoc for Method#invoke()  
says this:

"If the underlying method is an instance method, it is invoked using  
dynamic method lookup as documented in The Java Language  
Specification, Second Edition, section 15.12.4.4; in particular,  
overriding based on the runtime type of the target object will occur."

However, maybe it could be static:

public static __bind(T t, WTKXSerializer serializer) { ... }

where T is the type of the class that contains an @Bind annotation  
(not a generic - the actual type). It could be Object, but there's no  
need for it to be since we know what type it is. Since it is a static  
method of the class, it will have access to the class's internal  
variables, but won't be overridden by a subclass.


On Jun 9, 2009, at 12:33 PM, Noel Grandin wrote:

> Unfortunately in Java, you can't invoke a specific subclass version of
> an overridden method.
>
> That means that either
> (a) you have to trust that each method correctly invokes super.__bind
> (b) we need a more complex scheme.
>
> Something like having each class X define a method
> public void __bind(X myself, WTKXSerializer serializer)
> And then WTKXSerializer#bind() could walk up the class hierarchy,
> and use reflection to find the __bind methods and invoke them.
>
> But maybe someone can come up with a scheme that involves less magic?
> (I like reflection, but it's best used in small doses).
>
>
> On Tue, Jun 9, 2009 at 17:14, Greg Brown<gk...@mac.com> wrote:
>> I think this will actually work, and won't require too many  
>> changes. The
>> bind processor can add the Bindable interface to every class that  
>> uses an
>> @Bind annotation. The interface would contain a single method:
>>
>> public void __bind(WTKXSerializer serializer);
>>
>> WTKXSerializer#bind() would check to see if the bound object  
>> implemented
>> Bindable; if so, it would walk up the object's class hierarchy  
>> looking for
>> subclasses that implement Bindable. When found, it would invoke the  
>> specific
>> __bind() method defined by the subclass.
>>
>> Sound right?
>>


Re: [DISCUSS] WTKX binding

Posted by Noel Grandin <no...@gmail.com>.
Unfortunately in Java, you can't invoke a specific subclass version of
an overridden method.

That means that either
(a) you have to trust that each method correctly invokes super.__bind
(b) we need a more complex scheme.

Something like having each class X define a method
 public void __bind(X myself, WTKXSerializer serializer)
And then WTKXSerializer#bind() could walk up the class hierarchy,
and use reflection to find the __bind methods and invoke them.

But maybe someone can come up with a scheme that involves less magic?
(I like reflection, but it's best used in small doses).


On Tue, Jun 9, 2009 at 17:14, Greg Brown<gk...@mac.com> wrote:
> I think this will actually work, and won't require too many changes. The
> bind processor can add the Bindable interface to every class that uses an
> @Bind annotation. The interface would contain a single method:
>
> public void __bind(WTKXSerializer serializer);
>
> WTKXSerializer#bind() would check to see if the bound object implemented
> Bindable; if so, it would walk up the object's class hierarchy looking for
> subclasses that implement Bindable. When found, it would invoke the specific
> __bind() method defined by the subclass.
>
> Sound right?
>

Re: [DISCUSS] WTKX binding

Posted by Greg Brown <gk...@mac.com>.
I think this will actually work, and won't require too many changes.  
The bind processor can add the Bindable interface to every class that  
uses an @Bind annotation. The interface would contain a single method:

public void __bind(WTKXSerializer serializer);

WTKXSerializer#bind() would check to see if the bound object  
implemented Bindable; if so, it would walk up the object's class  
hierarchy looking for subclasses that implement Bindable. When found,  
it would invoke the specific __bind() method defined by the subclass.

Sound right?


On Jun 9, 2009, at 10:15 AM, Noel Grandin wrote:

>
> What I'm saying is that at the cost of some added complexity in the
> BindProcessor,
> we can  (1) bind to subclasses and (2) support binding in untrusted  
> code.
>
> Greg Brown wrote:
>> Bound member variables may be private, and reflection code isn't
>> allowed to set them in an unsigned applet. The bind processor  
>> rewrites
>> the code at compile and inserts methods into the Bindable subclasses
>> that can see the private members. So, we need Bindable to support
>> binding in untrusted code. I'm suggesting that we get rid of it
>> because we can't use it to meet a common use case (binding to Window
>> subclasses), and it relies on undocumented features of javac. Also,
>> the code itself is non-trivial.
>>
>> Although we couldn't use it in untrusted code, the reflection code
>> would still work fine, which is why I suggested that we might want to
>> keep it. However, it doesn't really save the developer that much  
>> work,
>> so we could just as easily eliminate it.
>


Re: [DISCUSS] WTKX binding

Posted by Greg Brown <gk...@mac.com>.
Possibly. The bind processor populates a bind() overload in each  
Bindable subclass that uses @Bind annotations. It is this method that  
gives us access to the private members of a bound class. The processor  
could still do this, even without a Bindable base class.

It's still a bit sketchy since it relies on undocumented javac  
features, but we overlooked that before and could conceivably continue  
to do so now. My question is - is it worth it? Does binding offer  
sufficient value to justify reliance on undocumented compiler  
features, plus the additional cost of maintaining the bind processor  
code?


On Jun 9, 2009, at 10:15 AM, Noel Grandin wrote:

>
> What I'm saying is that at the cost of some added complexity in the
> BindProcessor,
> we can  (1) bind to subclasses and (2) support binding in untrusted  
> code.
>
> Greg Brown wrote:
>> Bound member variables may be private, and reflection code isn't
>> allowed to set them in an unsigned applet. The bind processor  
>> rewrites
>> the code at compile and inserts methods into the Bindable subclasses
>> that can see the private members. So, we need Bindable to support
>> binding in untrusted code. I'm suggesting that we get rid of it
>> because we can't use it to meet a common use case (binding to Window
>> subclasses), and it relies on undocumented features of javac. Also,
>> the code itself is non-trivial.
>>
>> Although we couldn't use it in untrusted code, the reflection code
>> would still work fine, which is why I suggested that we might want to
>> keep it. However, it doesn't really save the developer that much  
>> work,
>> so we could just as easily eliminate it.
>


Re: [DISCUSS] WTKX binding

Posted by Noel Grandin <no...@gmail.com>.
What I'm saying is that at the cost of some added complexity in the
BindProcessor,
we can  (1) bind to subclasses and (2) support binding in untrusted code.

Greg Brown wrote:
> Bound member variables may be private, and reflection code isn't
> allowed to set them in an unsigned applet. The bind processor rewrites
> the code at compile and inserts methods into the Bindable subclasses
> that can see the private members. So, we need Bindable to support
> binding in untrusted code. I'm suggesting that we get rid of it
> because we can't use it to meet a common use case (binding to Window
> subclasses), and it relies on undocumented features of javac. Also,
> the code itself is non-trivial.
>
> Although we couldn't use it in untrusted code, the reflection code
> would still work fine, which is why I suggested that we might want to
> keep it. However, it doesn't really save the developer that much work,
> so we could just as easily eliminate it.


Re: [DISCUSS] WTKX binding

Posted by Greg Brown <gk...@mac.com>.
Bound member variables may be private, and reflection code isn't  
allowed to set them in an unsigned applet. The bind processor rewrites  
the code at compile and inserts methods into the Bindable subclasses  
that can see the private members. So, we need Bindable to support  
binding in untrusted code. I'm suggesting that we get rid of it  
because we can't use it to meet a common use case (binding to Window  
subclasses), and it relies on undocumented features of javac. Also,  
the code itself is non-trivial.

Although we couldn't use it in untrusted code, the reflection code  
would still work fine, which is why I suggested that we might want to  
keep it. However, it doesn't really save the developer that much work,  
so we could just as easily eliminate it.


On Jun 9, 2009, at 9:34 AM, Noel Grandin wrote:

> Why exactly do we need that?
>
> It seems to me that it should be possible to create a AppletBindable
> interface,
> and for the BindProcessor to add that interface to the relevant  
> classes,
> and inject some code (as it does currently).
>
> Am I missing something?
>
> Greg Brown wrote:
>> We actually do need a Bindable base class in order to support binding
>> in untrusted code. However, if we decide to drop support for that, we
>> could move the bind() method to WTKXSerializer and eliminate  
>> Bindable.
>> Is that consistent with what you are suggesting?
>>
>> On Jun 9, 2009, at 2:36 AM, Noel Grandin wrote:
>>
>>> Hi
>>>
>>> How about
>>> (3) Drop Bindable as a class altogether, and make the binding  
>>> process
>>> work without it.
>>> I don't see that class really need to implement it anyhow.
>>> Either that or make it an interface, and make the necessary classes
>>> implement it.
>>>
>>> Regards, Noel.
>


Re: [DISCUSS] WTKX binding

Posted by Noel Grandin <no...@gmail.com>.
Why exactly do we need that?

It seems to me that it should be possible to create a AppletBindable
interface,
and for the BindProcessor to add that interface to the relevant classes,
and inject some code (as it does currently).

Am I missing something?

Greg Brown wrote:
> We actually do need a Bindable base class in order to support binding
> in untrusted code. However, if we decide to drop support for that, we
> could move the bind() method to WTKXSerializer and eliminate Bindable.
> Is that consistent with what you are suggesting?
>
> On Jun 9, 2009, at 2:36 AM, Noel Grandin wrote:
>
>> Hi
>>
>> How about
>> (3) Drop Bindable as a class altogether, and make the binding process
>> work without it.
>> I don't see that class really need to implement it anyhow.
>> Either that or make it an interface, and make the necessary classes
>> implement it.
>>
>> Regards, Noel.


Re: [DISCUSS] WTKX binding

Posted by Sandro Martini <sa...@gmail.com>.
Hi Greg,

> We actually do need a Bindable base class in order to support binding in
> untrusted code. However, if we decide to drop support for that, we could
> move the bind() method to WTKXSerializer and eliminate Bindable. Is that
> consistent with what you are suggesting?
I think yes (but I've never used Bindable, so I can't tell you more in
detail) ... or if not to drop it (until the real 1.3 release), why not
move in another subproject like the "developer_subproject" (for a
1.2.x) ?
You say it can work this way ?

But for the maintenance release 1.2.x containing only the
simplification code you said before (for example on Resources and
WTKXSerializer), what do you think, with these modifications could it
work ?

Thanks,
Sandro

Re: [DISCUSS] WTKX binding

Posted by Greg Brown <gk...@mac.com>.
We actually do need a Bindable base class in order to support binding  
in untrusted code. However, if we decide to drop support for that, we  
could move the bind() method to WTKXSerializer and eliminate Bindable.  
Is that consistent with what you are suggesting?

On Jun 9, 2009, at 2:36 AM, Noel Grandin wrote:

> Hi
>
> How about
> (3) Drop Bindable as a class altogether, and make the binding process
> work without it.
> I don't see that class really need to implement it anyhow.
> Either that or make it an interface, and make the necessary classes
> implement it.
>
> Regards, Noel.
>
> Greg Brown wrote:
>> Hi all,
>>
>> I've recently been working on a "real-world" app using Pivot, and  
>> I've
>> run into a situation where I'd like to use WTKX binding, but I can't.
>> I want to create a FileBrowserSheet class that extends Sheet and  
>> loads
>> its contents from a WTKX file.
>>
>> In order for a Sheet subclass to take advantage of binding to process
>> the WTKX, Sheet would somehow need to extend Bindable. However,
>> Sheet's root base class is Component, which currently extends Object.
>> We could conceivably make Component extend Bindable; however, we
>> decided a while back for a variety of reasons that WTK classes should
>> not be dependent on WTKX, and I would prefer to stick with that  
>> decision.
>>
>> I think it will be fairly common for developers to want to bind to
>> application-specific Window subclasses; for example, LoginDialog,
>> FileOpenDialog, ContactInfoSheet, etc. I also think that any
>> non-trivial application will want to define a main application window
>> class rather than embedding the UI details in the application itself.
>> For example, I might define MyApplication that implements  
>> Application,
>> and MyApplicationWindow that extends Window. MyApplication would
>> simply serve as the entry point into the application, playing the  
>> same
>> role as the main() method in a typical Java application. We wouldn't
>> be able to use binding in any of these use cases.
>>
>> I see two options for resolving this issue:
>>
>> 1) Continue to support Bindable, but move it out of pivot.wtkx,
>> possibly to pivot.util or pivot.wtk. As a result of this move, we
>> would lose support for @Load, since it depends on WTKXSerializer.
>> However, we could retain support for @Bind.
>>
>> 2) Eliminate Bindable altogether. This seems drastic, especially  
>> since
>> the annotations do tend to clean up the code a bit. However, there is
>> a lot of code behind that support that needs to be maintained, and  
>> I'm
>> not sure it is justified.
>>
>> I'm leaning pretty strongly towards #2. This is what the code in my
>> FileBrowserSheet constructor looks like without binding (I'm assuming
>> the existence of a template parameter in WTKXSerializer - that can be
>> discussed as another topic, if necessary):
>>
>> Resources resources = new Resources(this);
>> setTitle(resources.getString("title"));
>>
>> WTKXSerializer<Component> wtkxSerializer = new
>> WTKXSerializer<Component>(resources);
>> setContent(wtkxSerializer.readObject(this, "file_browser.wtkx"));
>>
>> folderTreeView = wtkxSerializer.get("folderTreeView");
>> okButton = wtkxSerializer.get("okButton");
>> cancelButton = wtkxSerializer.get("cancelButton");
>>
>> With binding, the final three lines would be replaced with bind(),
>> which is very concise. However, the above code is still pretty
>> readable. Yes, we have to manually assign the member variables, but  
>> is
>> that really that much of a burden on developers? Is the  
>> simplification
>> offered by the bind() method enough to justify the additional code
>> maintenance of the Bindable class and the bind processor?
>>
>> The bind processor is what we use to rewrite the Bindable class files
>> at compile time so they can run in an untrusted applet. It is worth
>> noting that the processor currently relies on undocumented features  
>> of
>> the javac compiler. When binding seemed like it might be more
>> generally useful, I thought that this would be an OK risk to take.
>> However, now I don't think so.
>>
>> I'm going to suggest that we eliminate the Bindable class and revert
>> to the previous way of loading and processing WTKX. I've made some
>> minor API additions that simplify the use of WTKXSerializer directly.
>> pivot.util.Resources now takes a base object or class, so you can  
>> write:
>>
>> Resources resources = new Resources(this);
>>
>> If your class is named com.foo.MyClass, it will automatically load
>> com.foo.MyClass.json.
>>
>> I also added a readObject() overload to WTKXSerializer that takes an
>> object and a resource name. Now, instead of this:
>>
>> wtkxSerializer.readObject(getClass().getResource("foo.wtkx"));
>>
>> you can write this:
>>
>> wtkxSerializer.readObject(this, "foo.wtkx");
>>
>> Again, minor changes, but they make the code that much more readable.
>>
>> I understand that @Bind is pretty convenient, but it can't currently
>> be used in what I suspect will be a common use case, and, in my
>> opinion, adapting it such that it can be used for this purpose makes
>> it less compelling (especially since it requires undocumented  
>> features
>> of the compiler). Please let me know what you think.
>>
>> Thanks,
>> Greg
>>
>>
>


Re: [DISCUSS] WTKX binding

Posted by Noel Grandin <no...@gmail.com>.
Hi

How about
(3) Drop Bindable as a class altogether, and make the binding process
work without it.
I don't see that class really need to implement it anyhow.
Either that or make it an interface, and make the necessary classes
implement it.

Regards, Noel.

Greg Brown wrote:
> Hi all,
>
> I've recently been working on a "real-world" app using Pivot, and I've
> run into a situation where I'd like to use WTKX binding, but I can't.
> I want to create a FileBrowserSheet class that extends Sheet and loads
> its contents from a WTKX file.
>
> In order for a Sheet subclass to take advantage of binding to process
> the WTKX, Sheet would somehow need to extend Bindable. However,
> Sheet's root base class is Component, which currently extends Object.
> We could conceivably make Component extend Bindable; however, we
> decided a while back for a variety of reasons that WTK classes should
> not be dependent on WTKX, and I would prefer to stick with that decision.
>
> I think it will be fairly common for developers to want to bind to
> application-specific Window subclasses; for example, LoginDialog,
> FileOpenDialog, ContactInfoSheet, etc. I also think that any
> non-trivial application will want to define a main application window
> class rather than embedding the UI details in the application itself.
> For example, I might define MyApplication that implements Application,
> and MyApplicationWindow that extends Window. MyApplication would
> simply serve as the entry point into the application, playing the same
> role as the main() method in a typical Java application. We wouldn't
> be able to use binding in any of these use cases.
>
> I see two options for resolving this issue:
>
> 1) Continue to support Bindable, but move it out of pivot.wtkx,
> possibly to pivot.util or pivot.wtk. As a result of this move, we
> would lose support for @Load, since it depends on WTKXSerializer.
> However, we could retain support for @Bind.
>
> 2) Eliminate Bindable altogether. This seems drastic, especially since
> the annotations do tend to clean up the code a bit. However, there is
> a lot of code behind that support that needs to be maintained, and I'm
> not sure it is justified.
>
> I'm leaning pretty strongly towards #2. This is what the code in my
> FileBrowserSheet constructor looks like without binding (I'm assuming
> the existence of a template parameter in WTKXSerializer - that can be
> discussed as another topic, if necessary):
>
> Resources resources = new Resources(this);
> setTitle(resources.getString("title"));
>
> WTKXSerializer<Component> wtkxSerializer = new
> WTKXSerializer<Component>(resources);
> setContent(wtkxSerializer.readObject(this, "file_browser.wtkx"));
>
> folderTreeView = wtkxSerializer.get("folderTreeView");
> okButton = wtkxSerializer.get("okButton");
> cancelButton = wtkxSerializer.get("cancelButton");
>
> With binding, the final three lines would be replaced with bind(),
> which is very concise. However, the above code is still pretty
> readable. Yes, we have to manually assign the member variables, but is
> that really that much of a burden on developers? Is the simplification
> offered by the bind() method enough to justify the additional code
> maintenance of the Bindable class and the bind processor?
>
> The bind processor is what we use to rewrite the Bindable class files
> at compile time so they can run in an untrusted applet. It is worth
> noting that the processor currently relies on undocumented features of
> the javac compiler. When binding seemed like it might be more
> generally useful, I thought that this would be an OK risk to take.
> However, now I don't think so.
>
> I'm going to suggest that we eliminate the Bindable class and revert
> to the previous way of loading and processing WTKX. I've made some
> minor API additions that simplify the use of WTKXSerializer directly.
> pivot.util.Resources now takes a base object or class, so you can write:
>
> Resources resources = new Resources(this);
>
> If your class is named com.foo.MyClass, it will automatically load
> com.foo.MyClass.json.
>
> I also added a readObject() overload to WTKXSerializer that takes an
> object and a resource name. Now, instead of this:
>
> wtkxSerializer.readObject(getClass().getResource("foo.wtkx"));
>
> you can write this:
>
> wtkxSerializer.readObject(this, "foo.wtkx");
>
> Again, minor changes, but they make the code that much more readable.
>
> I understand that @Bind is pretty convenient, but it can't currently
> be used in what I suspect will be a common use case, and, in my
> opinion, adapting it such that it can be used for this purpose makes
> it less compelling (especially since it requires undocumented features
> of the compiler). Please let me know what you think.
>
> Thanks,
> Greg
>
>


Re: [DISCUSS] WTKX binding

Posted by Greg Brown <gk...@mac.com>.
> 1) Continue to support Bindable, but move it out of pivot.wtkx,  
> possibly to pivot.util or pivot.wtk. As a result of this move, we  
> would lose support for @Load, since it depends on WTKXSerializer.  
> However, we could retain support for @Bind.

In case it wasn't clear, the implication of this change would be that  
Component could then concievably extend Bindable. However, I still  
think #2 is a better option, for the reasons outlined in the previous  
message.


Re: [DISCUSS] WTKX binding

Posted by Sandro Martini <sa...@gmail.com>.
Hi Greg,
also for me your choice #2 seems the best, having simpler code (and
without distinction on trusted and untrusted execution ) is more
useful ...

In my experiments, i tried something with annotations, and in some
cases they are very useful, but instead of implementing them in one of
pivot subprojects, what do you think on moving them (if existing here,
after cleanup) in a dedicated subproject (like the tools subproject),
but only for development environment (for compile-time utilities, from
IDE, or Ant) ?


> Resources resources = new Resources(this);
>
> If your class is named com.foo.MyClass, it will automatically load
> com.foo.MyClass.json.
>
> I also added a readObject() overload to WTKXSerializer that takes an object
> and a resource name. Now, instead of this:
>
> wtkxSerializer.readObject(getClass().getResource("foo.wtkx"));
>
> you can write this:
>
> wtkxSerializer.readObject(this, "foo.wtkx");
>
> Again, minor changes, but they make the code that much more readable.
>

This is great, so a question:
if all these are little modifications to the current (post 1.2 trunk),
what do you think on release these (including others, if needed)
before the 1.3 ?
Could we think on a maintenance 1.2.x in the short term ?
In this way we and our users could try this before the full cleanup
(Bindable, the package refactoring, etc), and see if it's not too much
complex.

In next months I'd like to start new applications, finally based on
Pivot, and starting with a post 1.2 release (or with a 1.3 trunk, but
i don't like too much this idea) would be great.
In any case, I'll tell of news on this ...


Ah, in the Web Site, if we could have also a "Real Use Cases" section,
could be useful ...


Thanks and good work,
Sandro

Re: [DISCUSS] WTKX binding

Posted by Greg Brown <gk...@mac.com>.
> Great monolog Greg, I was waiting for another installment. :)

Ha. That's all for now. Sorry.  :-)

> To be honest, I have no particular feelings one way or another, so  
> am happy
> to go with what you decide.

Cool.

> FYI, I am putting together an architecture document for an up coming  
> project
> (which hopefully will kick off in July/August) and I am going to  
> propose
> Pivot for one of the UIs, so
> until then I am happy for things like this to be in a state of 'flux'.

That's great. Definitely let us know how that goes.


Re: [DISCUSS] WTKX binding

Posted by Christopher Brind <br...@brindy.org.uk>.
Great monolog Greg, I was waiting for another installment. :)
To be honest, I have no particular feelings one way or another, so am happy
to go with what you decide.

FYI, I am putting together an architecture document for an up coming project
(which hopefully will kick off in July/August) and I am going to propose
Pivot for one of the UIs, so
until then I am happy for things like this to be in a state of 'flux'.

Cheers,
Chris



2009/6/8 Greg Brown <gk...@mac.com>

> I see two options for resolving this issue:
>>
>> 1) Continue to support Bindable, but move it out of pivot.wtkx, possibly
>> to pivot.util or pivot.wtk. As a result of this move, we would lose support
>> for @Load, since it depends on WTKXSerializer. However, we could retain
>> support for @Bind.
>>
>> 2) Eliminate Bindable altogether. This seems drastic, especially since the
>> annotations do tend to clean up the code a bit. However, there is a lot of
>> code behind that support that needs to be maintained, and I'm not sure it is
>> justified.
>>
>
> A third alternative is to continue to support binding, but only for trusted
> code. That would eliminate the the need for the bind processor as well as
> the need to extend a Bindable base class. Obviously, the downside is that it
> is not a universal solution since it couldn't be used in unsigned applets.
>
> If we decide to take this approach, I would suggest moving the bind()
> method back into WTKXSerializer:
>
> public void bind(Object object) throws BindException { ... }
>
> This would allow us to use it on any class, not just instances of Bindable.
>
> Note that this method is not static - it would operate on instances of
> WTKXSerializer that had already been called to readObject(). So we still
> wouldn't need @Load, but we could support @Bind.
>
>
>

Re: [DISCUSS] WTKX binding

Posted by Greg Brown <gk...@mac.com>.
> I see two options for resolving this issue:
>
> 1) Continue to support Bindable, but move it out of pivot.wtkx,  
> possibly to pivot.util or pivot.wtk. As a result of this move, we  
> would lose support for @Load, since it depends on WTKXSerializer.  
> However, we could retain support for @Bind.
>
> 2) Eliminate Bindable altogether. This seems drastic, especially  
> since the annotations do tend to clean up the code a bit. However,  
> there is a lot of code behind that support that needs to be  
> maintained, and I'm not sure it is justified.

A third alternative is to continue to support binding, but only for  
trusted code. That would eliminate the the need for the bind processor  
as well as the need to extend a Bindable base class. Obviously, the  
downside is that it is not a universal solution since it couldn't be  
used in unsigned applets.

If we decide to take this approach, I would suggest moving the bind()  
method back into WTKXSerializer:

public void bind(Object object) throws BindException { ... }

This would allow us to use it on any class, not just instances of  
Bindable.

Note that this method is not static - it would operate on instances of  
WTKXSerializer that had already been called to readObject(). So we  
still wouldn't need @Load, but we could support @Bind.