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