0

In my Java application I'm using an object-oriented interpreted script language (specified using ANTLR) and would like to use that together with Velocity.

An object in my language is represented by an instance of DataObject, which looks like this (simplified):

public class DataObject {
    protected Map<String, Object> properties;

    public Map<String, DataEntity> getProperties() {
        return properties;
    }

    public Object getProperty(String name) {
        return properties.get(name);
    }
}

and the properties of an object instance $foo could be accessed as $foo.bar

Now let's assume I have put $foo into my VelocityContext:

DataObject foo = new DataObject();
velocityContext.put("foo", foo);

As far as I know, I could then access the properties (which reside in DataObject.properties) in velocity in any of these ways:

<span>$foo.getProperties().get('bar')</span>
<span>$foo.getProperties()['bar']</span>
<span>$foo.getProperties().bar</span>
<span>$foo.properties.bar</span>

Now to my main question: Is there a way to change the behavior such that $foo.bar would not address the Java property dataObject.bar, but rather directly dataObject.properties.get("bar"), so that I could use $foo.bar inside Velociy just as I would in my own script language?

usimon
  • 415
  • 1
  • 5
  • 8

1 Answers1

2

You can't teach Velocity that trick. But you can teach DataObject the trick:

public class DataObject {
    protected Map<String, Object> properties;

    public Map<String, DataEntity> getProperties() {
        return properties;
    }

    public Object get(String name) {
        return properties.get(name);
    }
}

Velocity will automatically look for a get('bar') in $foo if it can't find a getBar() or getbar() method.

Nathan Bubna
  • 6,823
  • 2
  • 35
  • 36
  • Thanks for your answer! Unfortunately, I don't have control over DataObject itself :-(. Before registering in the Velocity context, I could wrap DataObject inside another Class that delegates get(String name) to getPropererty(String name); but this would only be a partial solution as many properties are in turn also DataObjects, so the construct $a.b.c would not be possible that way. Do you know where in Velocity the behavior you mentioned is defined? A small (local) adaption to the core library might better suit my needs – usimon Jun 29 '12 at 20:09
  • You can probably achieve this with a custom Uberspect implementation; these can be configured via velocity.properties. You'll have to google around for examples and instructions, i haven't time right now. – Nathan Bubna Jul 02 '12 at 17:20
  • Awesome, thanks for this hint! I had a quick look into it and it seems to fully cover my requirements :-). I'll give it a try and write my own Uberinspector – usimon Jul 06 '12 at 11:17