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 ?