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