Velocity
  1. Velocity
  2. VELOCITY-12

Access to public member variable of a class

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 1.1
    • Fix Version/s: 2.x
    • Component/s: Engine
    • Labels:
      None
    • Environment:
      Operating System: All
      Platform: PC

      Description

      It would be nice if I could reference public instance variables in a class that
      is put in the velocity context using a syntax such as
      $theClass.instanceVarName. I am aware that this syntax is used to reference
      the getInstanceVarName() method of the class that is put in the context...maybe
      a variation on the syntax could be used for instance variables. I am also
      aware that it is probably not good to expose instance variables as public,
      however the classes I am dealing with are generated via a CORBA IDL compiler.
      My servlet makes a CORBA call, which returns data in such an object (public
      instance vars, no accessor methods), and it would be nice if I could stuff this
      object into the velocity context and reference it directly in a template. What
      I have to do with the current implementation of velocity is wrap these IDL
      compiler generated classes to provide get methods for the instance variables.
      This is very easy, but adds up to a lot of classes that exist merely so public
      members can be accessed via a get method.

      <bootlickingon> I evaluated velocity as an alternative to JSP for use on my
      current project, and Velocity wins hands down, even given this
      inconvenience.</bootlickingoff>

      1. VELOCITY-12.patch
        26 kB
        Candid Dauth

        Activity

        Hide
        Geir Magnusson Jr added a comment -

        While I must admit that the <bootlickingon> bit almost did it for me, I do note
        that any decent XML parser would choke on it as the closing tag didn't match the
        opening tag

        Seriously - we provide a little tool to help with this called
        org.apache.velocity.app.FieldMethodizer. You use like this :

        context.put("thingy", new FieldMethodizer( thingy ) );

        and then you should be able to access any public static field. I can't remember
        why we limit to static's, so that may provide an opportunity for enhancement if
        you need to access non-statics.

        You also could use the FieldMethodizer as a model for a tool more appropriate
        for your needs as well. Let us know how this works out.

        Show
        Geir Magnusson Jr added a comment - While I must admit that the <bootlickingon> bit almost did it for me, I do note that any decent XML parser would choke on it as the closing tag didn't match the opening tag Seriously - we provide a little tool to help with this called org.apache.velocity.app.FieldMethodizer. You use like this : context.put("thingy", new FieldMethodizer( thingy ) ); and then you should be able to access any public static field. I can't remember why we limit to static's, so that may provide an opportunity for enhancement if you need to access non-statics. You also could use the FieldMethodizer as a model for a tool more appropriate for your needs as well. Let us know how this works out.
        Hide
        Rich Doyle added a comment -

        It looks like the FieldMethodizer will do the trick with a simple modification
        to allow it to access non-static members. (Line 203 of FieldMethodizer.java)
        The reasoning in the source code for only providing access to statics is that
        it is "too dangerous" to allow access to other fields. This is a valid
        concern, however my opinion is that if a field is defined public, it is not
        dangerous to allow it to be accessed. If it is, the class designer should not
        make it public. Don't get me wrong...I am not a fan of public non-statics,
        however in my case, the IDL compiler creates the classes this way (as specified
        by the CORBA java language mapping) so I have no choice but to deal with it.
        Thanks for your help!

        Show
        Rich Doyle added a comment - It looks like the FieldMethodizer will do the trick with a simple modification to allow it to access non-static members. (Line 203 of FieldMethodizer.java) The reasoning in the source code for only providing access to statics is that it is "too dangerous" to allow access to other fields. This is a valid concern, however my opinion is that if a field is defined public, it is not dangerous to allow it to be accessed. If it is, the class designer should not make it public. Don't get me wrong...I am not a fan of public non-statics, however in my case, the IDL compiler creates the classes this way (as specified by the CORBA java language mapping) so I have no choice but to deal with it. Thanks for your help!
        Hide
        Henning Schmiedehausen added a comment -

        Close all resolved issues for older releases.

        Show
        Henning Schmiedehausen added a comment - Close all resolved issues for older releases.
        Hide
        Candid Dauth added a comment -

        I would really like to see this implemented. In my opinion it is the most expected and obvious behaviour that $test.bla can be resolved when the object has a public property bla. It seems stupid to me that currently, you cannot access that data without using a helper function.

        I have created a patch to fix this issue in velocity 1.7. As I don’t seem to be able to upload attachments here, it is available on http://pastebin.com/QqABn90y. Also, as I rely on this feature myself, I have checked in the source code on https://gitorious.org/cdauth/velocity and have made it available via Maven on http://mvn.cdauth.eu/releases/org/apache/velocity/velocity/.

        Show
        Candid Dauth added a comment - I would really like to see this implemented. In my opinion it is the most expected and obvious behaviour that $test.bla can be resolved when the object has a public property bla. It seems stupid to me that currently, you cannot access that data without using a helper function. I have created a patch to fix this issue in velocity 1.7. As I don’t seem to be able to upload attachments here, it is available on http://pastebin.com/QqABn90y . Also, as I rely on this feature myself, I have checked in the source code on https://gitorious.org/cdauth/velocity and have made it available via Maven on http://mvn.cdauth.eu/releases/org/apache/velocity/velocity/ .
        Hide
        Will Glass-Husain added a comment -

        Wow - old bug! Thanks for contributing. Not sure why you couldn't upload-- do try again at some point please. Part of this process indicates that you are agreeing to license your code under the Apache License 2.0.

        One way you can address this need without doing a custom build is to create your own Uberspector. This is a plugin which does the reflection to make the actual method calls. It's not hard. I wrote one to let Velocity iterate over a JSONlib array in my app and it was just a couple of lines. You can base it on the default implementation or just subclass it, test for public fields first, the delegate to the parent class.

        WILL

        Show
        Will Glass-Husain added a comment - Wow - old bug! Thanks for contributing. Not sure why you couldn't upload-- do try again at some point please. Part of this process indicates that you are agreeing to license your code under the Apache License 2.0. One way you can address this need without doing a custom build is to create your own Uberspector. This is a plugin which does the reflection to make the actual method calls. It's not hard. I wrote one to let Velocity iterate over a JSONlib array in my app and it was just a couple of lines. You can base it on the default implementation or just subclass it, test for public fields first, the delegate to the parent class. WILL
        Hide
        Nathan Bubna added a comment -

        Yeah, please attach the patch to this issue, so we can use it without license concerns.

        Personally, i'm not very opposed to the idea anymore. Of course, i don't need it and won't use it, as i do still see cases where java devs might want something to be public but not accessible in a template, but i also think it should be easier to override that default than it is. I think it makes sense to ship an Uberspect impl that supports this, so it is just a property change away for users that want it.

        Show
        Nathan Bubna added a comment - Yeah, please attach the patch to this issue, so we can use it without license concerns. Personally, i'm not very opposed to the idea anymore. Of course, i don't need it and won't use it, as i do still see cases where java devs might want something to be public but not accessible in a template, but i also think it should be easier to override that default than it is. I think it makes sense to ship an Uberspect impl that supports this, so it is just a property change away for users that want it.
        Hide
        Candid Dauth added a comment -

        The upload form should be in the “More Actions” menu, right? It isn’t there, maybe because the bug is closed? And I don’t see a way to reopen it.

        Show
        Candid Dauth added a comment - The upload form should be in the “More Actions” menu, right? It isn’t there, maybe because the bug is closed? And I don’t see a way to reopen it.
        Hide
        Candid Dauth added a comment -

        I have uploaded a new version of the patch to http://pastebin.com/HkJN2PaU.

        Instead of modifying the default behaviour, I have created the class org.apache.velocity.util.introspection.UberspectPublicFields. As documented on http://velocity.apache.org/engine/devel/developer-guide.html#Velocity_Configuration_Keys_and_Values, in order to use this modification, the Velocity property runtime.introspector.uberspect needs to be set to org.apache.velocity.util.introspection.UberspectImpl,org.apache.velocity.util.introspection.UberspectPublicFields.

        Personally, I can’t imagine cases where developers don’t want public fields to be read/modified. Thus I would prefer to have this as default behaviour, as that would lead to less confusion.

        Show
        Candid Dauth added a comment - I have uploaded a new version of the patch to http://pastebin.com/HkJN2PaU . Instead of modifying the default behaviour, I have created the class org.apache.velocity.util.introspection.UberspectPublicFields. As documented on http://velocity.apache.org/engine/devel/developer-guide.html#Velocity_Configuration_Keys_and_Values , in order to use this modification, the Velocity property runtime.introspector.uberspect needs to be set to org.apache.velocity.util.introspection.UberspectImpl,org.apache.velocity.util.introspection.UberspectPublicFields. Personally, I can’t imagine cases where developers don’t want public fields to be read/modified. Thus I would prefer to have this as default behaviour, as that would lead to less confusion.
        Hide
        Nathan Bubna added a comment -

        You're probably thinking of simple member types in apps where the developer also writes the templates.

        Anyway, thanks for contributing the Uberspect. I'll re-open the issue. Hopefully that makes the attachment option appear. I'm still getting used to this new JIRA version though.

        Show
        Nathan Bubna added a comment - You're probably thinking of simple member types in apps where the developer also writes the templates. Anyway, thanks for contributing the Uberspect. I'll re-open the issue. Hopefully that makes the attachment option appear. I'm still getting used to this new JIRA version though.
        Hide
        Candid Dauth added a comment -

        Yep, now it worked. I’ve attached the patch.

        Show
        Candid Dauth added a comment - Yep, now it worked. I’ve attached the patch.

          People

          • Assignee:
            Claude Brisson
            Reporter:
            Rich Doyle
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development