Allen:

You raise some good points.

I'm ok with using XDoclet to generate the wrappers directly, and also recognize that there may be more issues with either implementation as you get down to the details. I'm happy to leave that to your judgement.

I think we all want low maintenance of the wrapping code. The dynamic proxy + X-Doclet-generated restriction interfaces idea was just a means to achieve this, and your suggestion of moving the delegation write into the X-doclet generated code should be fine too.

--a.


----- Original Message ----- From: "Allen Gilliland" <[EMAIL PROTECTED]>
To: "roller-dev" <[email protected]>
Sent: Tuesday, July 12, 2005 3:16 PM
Subject: Re: velocity context cleanup


I was just thinking about this a little more and I am actually starting to think that the dynamic proxy might not be the better approach. If we are going to have xdoclet auto generate the restricted interfaces, then why not have it generate wrapper classes instead?

The big bonus I see with the wrapper classes is that we get compile time validation that a wrapper exists for the pojo and that the coder has applied the right wrapper. With the dynamic proxy you could easily call ctx.put("obj", VelocityWrapper.wrap(myPojo)) but you don't find out if there is something wrong until runtime.

My other slight uneasyness with the proxy solution (and this is mainly a pet peeve) is that it makes me uncomfortable when a class implements an interface that is not generated until build time. Auto generated wrapper classes isn't a whole lot better, but I still prefer to have important core code like pojos to not be reliant on auto generated code if possible.

I am still okay with the proxy solution if that's what everyone else wants, but my personal preference is to avoid mucking with things at runtime when we don't really need to.

-- Allen


On Sun, 2005-07-10 at 08:27, Anil Gangolli wrote:
An additional suggestion: the "restriction interfaces" (see below) could be constructed using XDoclet, so that we could just tag the
bean methods to be exposed.  One has to write a suitable XDoclet template for 
it, though.

--a.



----- Original Message ----- From: "Dave Johnson" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Friday, July 08, 2005 3:40 PM
Subject: Re: velocity context cleanup


>
> +1 on dynamic proxies!
>
> - Dave
>
>
> On Jul 6, 2005, at 11:17 AM, Anil Gangolli wrote:
>
>>
>> Yes, I meant using the dynamic proxy facilities introduced in Java 1.3 (see, 
e.g.
>> http://java.sun.com/j2se/1.3/docs/guide/reflection/proxy.html).
>>
>> I apologize for the terseness.  Here's a more complete description.
>>
>> Note that the success of this approach willl hinge on the reflection of the proxy class seen by Velocity as being the >> restricted
>> interface desired to be exposed.  Reading "Proxy Class Properties" in the 
above document, this should be the case.
>>
>> (1) Define a simple invocation handler class whose invoke() method just does 
an m.invoke(obj) on the passed in params,
>>     and just unwraps InvocationTargetException to throw back any originating 
Throwable it contains.
>>     See the examples in the doc above.
>>
>> (2) Define your restriction interfaces whose names can be derived by 
convention from the name of the associated POJO
>>     (like org.roller.pojos.Template -> 
org.roller.presentation.velocity.wrappers.Template or TemplateWrapper).  You must
>>     define an interface to use a dynamic proxy.
>>
>> (3) Define a single proxy factory method wrap() that generates a proxy.  
[With the following example code it would be
>> VelocityWrapper.wrap(thePojo)].  You just call this and place the result 
into the Velocity context.
>>
>> Here is APPROXIMATE pseudo-code for illustration. Note: this won't compile for sure without a createWrapperFromPojoName() >> method
>> defined. You can get the intent anyway.
>>
>>    public class VelocityWrapper {
>>
>>        public static Object wrap(Object pojo) {
>>             // Determine the wrapper interface class name from the pojo 
class name
>>             String restrictionInterfaceName = 
createWrapperNameFromPojoName(pojo.getClass().getName());
>>             // Get that class an return a proxy instance with the invocation 
handler below.
>>             Class restrictionInterface = 
pojo.getClass().getClassLoader().loadClass(restrictionInterfaceName);
>>             SimpleInvocationHandler handler = new 
SimpleInvocationHandler(pojo);
>>             return Proxy.newProxyInstance(pojo.getClass().getClassLoader,
>>                                                           new Class[] {  
restrictionInterface },
>>                                                           handler);
>>         }
>>
>>        public static class SimpleInvocationHandler implements 
InvocationHandler {
>>                private Object theWrappedPojo;
>>
>>                SimpleInvocationHandler(Object pojo) {
>>                   // When constructed, remember the instance we were 
constructed with
>>                   theWrappedPojo = pojo;
>>                }
>>
>>                public Object invoke(Object proxy, method m, Object[] args) 
throws Throwable {
>>                    try {
>>                        return m.invoke(theWrappedPojo, args);
>>                    } catch (InvocationTargetException e) {
>>                        // rethrow the original exception to make the 
wrapping transparent
>>                        throw e.getTargetException();
>>                    }
>>                }
>>        }
>>    }
>>
>>
>>
>>
>>
>> ----- Original Message ----- From: "Rudman Max" <[EMAIL PROTECTED]>
>> To: <[email protected]>
>> Sent: Tuesday, July 05, 2005 10:07 PM
>> Subject: Re: velocity context cleanup
>>
>>
>>> I think he is talking about dynamic proxy facilities provided by java.lang.reflect.Proxy. Instead of creating a wrapper >>> class
>>> for each POJO you could deposit a dynamically proxy class in the Velocity  
context constructed with InvocationHandler
>>> implementation which  blocks all method calls unless they begin with 
"set/is". I personally think this a really good idea.
>>>
>>> Max
>>>
>>> On Jul 6, 2005, at 12:50 AM, Allen Gilliland wrote:
>>>
>>>> I'm not sure what you mean by dynamic proxy.  Could you give more  info.
>>>>
>>>> -- Allen
>>>>
>>>>
>>>> Anil Gangolli wrote:
>>>>
>>>>
>>>>>
>>>>> Just a quick note, and I admit I haven't followed the latest  discussion, 
but if the wrappers are merely restrictions by a
>>>>> specified interface, it seems like a single dynamic proxy could  
implement all of them.
>>>>>
>>>>> --a.
>>>>>
>>>>> ----- Original Message ----- From: "Allen Gilliland"  <[EMAIL PROTECTED]>
>>>>> To: <[email protected]>
>>>>> Sent: Tuesday, July 05, 2005 3:31 PM
>>>>> Subject: Re: velocity context cleanup
>>>>>
>>>>>
>>>>>
>>>>>> agreed.  so the convention will be ...
>>>>>>    org.roller.presentation.velocity.wrappers.<POJO Class>Wrapper
>>>>>>
>>>>>> will act as a wrapper class for a <POJO Class> normally found in  
org.roller.pojos
>>>>>>
>>>>>> -- Allen
>>>>>>
>>>>>>
>>>>>> Lance Lavandowska wrote:
>>>>>>
>>>>>>
>>>>>>> Ooops, you caught me not paying sufficient attention, even whilst I
>>>>>>> was typing out the package name!  Hmm, I think I like  o.r.p.v.wrappers
>>>>>>> better, less confusion with the "real" "pojos".
>>>>>>>
>>>>>>> On 7/5/05, Allen Gilliland <[EMAIL PROTECTED]> wrote:
>>>>>>>
>>>>>>>
>>>>>>>> i can do that, but org.roller.presentation.velocity.pojos *is*  a new
>>>>>>>> sub-package.  maybe org.roller.presentation.velocity.wrappers  would be
>>>>>>>> more clear?
>>>>>>>>
>>>>>>>> -- Allen
>>>>>>>>
>>>>>>>>
>>>>>>>> Lance Lavandowska wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>> Just one suggestion, put the wrappers in a sub-package, perhaps
>>>>>>>>> org.roller.presentation.velocity.pojos.wrappers ?
>>>>>>>>>
>>>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>
>



Reply via email to