Immutable pojos as context objects
I was wondering if there is a convenient way to restrict method calls on objects I put into VelocityContext. I use Velocity templates to do dynamic renders high-traffic websites, and I instantiate VelocityEngine objects along with various POJOs that Spring assembles. These POJOs are sort of like macros and/or scripting support, have been configured with setter-injection, and are exposed to templates using a VelocityContext object. My problem is that I intend to reuse these VelocityEngine and POJOs across multiple requests, so I do not want to allow template authors to call setter methods and effectively reconfigure the POJOs. Is there an easy way to either have Velocity prevent certain method calls on context objects, or otherwise a way to make these POJOs immutable? -- Serge Knystautas Lokitech software . strategy . design http://www.lokitech.com p. 301.656.5501 e. [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Immutable pojos as context objects
Serge Knystautas [EMAIL PROTECTED] wrote: I was wondering if there is a convenient way to restrict method calls on objects I put into VelocityContext. I use Velocity templates to do dynamic renders high-traffic websites, and I instantiate VelocityEngine objects along with various POJOs that Spring assembles. These POJOs are sort of like macros and/or scripting support, have been configured with setter-injection, and are exposed to templates using a VelocityContext object. My problem is that I intend to reuse these VelocityEngine and POJOs across multiple requests, so I do not want to allow template authors to call setter methods and effectively reconfigure the POJOs. Is there an easy way to either have Velocity prevent certain method calls on context objects, Well, the easy answer to this part of the question is to implement a custom Uberspect. http://jakarta.apache.org/velocity/api/org/apache/velocity/util/introspection/Uberspect.html There's examples of this on the wiki: http://wiki.apache.org/jakarta-velocity/MultiUberspect http://wiki.apache.org/jakarta-velocity/LuceneDocumentUberspect or otherwise a way to make these POJOs immutable? Outside of the scope of velocity, but really the heart of the problem even with a custom Uberspect. At some point you either need to enumerate all objects you want to be immutable (or mutable), or you need to only stick immutable objects into the context. Personally, I think the second method is easier and safer. Why don't you stick your POJOs into the template as a wrapper object (delegate), with only the getter methods exposed? - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Immutable pojos as context objects
Mike Kienenberger wrote: Well, the easy answer to this part of the question is to implement a custom Uberspect. http://jakarta.apache.org/velocity/api/org/apache/velocity/util/introspection/Uberspect.html There's examples of this on the wiki: http://wiki.apache.org/jakarta-velocity/MultiUberspect http://wiki.apache.org/jakarta-velocity/LuceneDocumentUberspect Thanks, I'll take a look. or otherwise a way to make these POJOs immutable? Outside of the scope of velocity, but really the heart of the problem even with a custom Uberspect. At some point you either need to enumerate all objects you want to be immutable (or mutable), or you need to only stick immutable objects into the context. Personally, I think the second method is easier and safer. Why don't you stick your POJOs into the template as a wrapper object (delegate), with only the getter methods exposed? Yes, I was looking for something more like this. I know this is tangential to Velocity, but figured it might be something others had faced when trying to restrict what template authors could do. I was looking to extend VelocityContext to add a putImmutable(key, object) method. This would create an AOP-style proxy object that will fail on any set method but otherwise just hand calls to the underlying POJO. Probably something CGLIB could do for me. -- Serge Knystautas Lokitech software . strategy . design http://www.lokitech.com p. 301.656.5501 e. [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Immutable pojos as context objects
Serge Knystautas [EMAIL PROTECTED] wrote: Mike Kienenberger wrote: Well, the easy answer to this part of the question is to implement a custom Uberspect. http://jakarta.apache.org/velocity/api/org/apache/velocity/util/introspection/Uberspect.html There's examples of this on the wiki: http://wiki.apache.org/jakarta-velocity/MultiUberspect http://wiki.apache.org/jakarta-velocity/LuceneDocumentUberspect I was looking to extend VelocityContext to add a putImmutable(key, object) method. This would create an AOP-style proxy object that will fail on any set method but otherwise just hand calls to the underlying POJO. Probably something CGLIB could do for me. Yeah, that's something you could do with an Uberspect. Set up something so you can do Uberspect.putImmutable(context, key, object) which will add it to the context, and add it to a list of objects to which you disallow set method calls. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Immutable pojos as context objects
Velocity itself has a rule to accept all public methods. It is up to the programmer to decide which methods to make available to Velocity by making the methods public. Velocity, even JAVA, has no way of knowing if a method will change the underlying class. Making a class immutable is up to the programmer. You could extend the underlying class, override the setter methods to do nothing, and pass this class to Velocity. public class MyImmutableClass extends MyClass { public MyImmutableClass(MyClass clazz) { this=clazz; } //Override setter methods and any other methods that //change the underlying class to do nothing public void setField(Object o) { } } Then for Velocity: MyClass clazz=new MyClass(...); //Make changes to clazz ctx.put(clazz,new MyImmutableClass(clazz)); //Now template designer cannot change clazz but can access all //other methods -- Whenever possible, I try to design classes from the start as immutable classes, following best practices. Have a constructor that gets all the information and then don't have any methods that would change it. This is not always convenient or possible, but can happen more often than you might think if you are creative. If you are creating objects from scratch that will be passed to Velocity, it is good to create them as immutable objects. Otherwise, it is relatively easy to add a boolean field that is checked before executing methods that would change the underlying object. Then have a method or constructor that provides a version of the underlying class with this boolean field set to false. Pass this immutable version of the class to the Velocity context. -- Barbara Baughman X2157 On Fri, 11 Feb 2005, Serge Knystautas wrote: I was wondering if there is a convenient way to restrict method calls on objects I put into VelocityContext. I use Velocity templates to do dynamic renders high-traffic websites, and I instantiate VelocityEngine objects along with various POJOs that Spring assembles. These POJOs are sort of like macros and/or scripting support, have been configured with setter-injection, and are exposed to templates using a VelocityContext object. My problem is that I intend to reuse these VelocityEngine and POJOs across multiple requests, so I do not want to allow template authors to call setter methods and effectively reconfigure the POJOs. Is there an easy way to either have Velocity prevent certain method calls on context objects, or otherwise a way to make these POJOs immutable? -- Serge Knystautas Lokitech software . strategy . design http://www.lokitech.com p. 301.656.5501 e. [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]