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 ?
>>>>>>>>>
>>>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>
>