34

I just start using Java Velocity. Now I want to create a java class template.

package $app.package_namespace
public class ${app.name}Station

{
    #foreach($s_attribute in $app.station)
         $s_attribute.type $s_attribute.name,
    #end
    public $app.name Station(#foreach($s_attribute in $app.station)
                                 $s_attribute.type $s_attribute.name;
                             #end)
{
    #foreach($s_attribute in $app.station)
          $s_attribute.name=$s_attribute.name;
    #end
}
#foreach($s_attribute in $app.station)
    public ${s_attribute.type} get${s_attribute.name}()
    {
        return  get${s_attribute.name}();
    }
#end
}

The problem is s_attribute.name first character is lowercase. When I create getter and setter function for attributes. I need change first character to uppercase.

Did anyone know how to do it?

Yiming
  • 383
  • 1
  • 4
  • 6

4 Answers4

43

You can invoke standard java methods on these objects. If s_attribute.name is type String you can directly use $s_attribute.name.toUpperCase() or for your specific case use $s_attribute.name.substring(0,1).toUpperCase() and $s_attribute.name.substring(1).toLowerCase()

adarshr
  • 61,315
  • 23
  • 138
  • 167
d-live
  • 7,926
  • 3
  • 22
  • 16
  • I hope you meant `toUpperCase` and `toLowerCase`? – adarshr Aug 09 '11 at 15:21
  • Yes, in this case the same macro would have to be applied twice once for the first character and once for the rest of the string. Personally this being the presentation layer I would avoid it. Also, on the second string doing `toLowerCase` is a bad idea, what if your validable is called customerName, you would want the method produced to be getCustomerName and not getCustomername. – Ali Aug 09 '11 at 15:22
  • @adarshr Oppa yes.. I did meant toUpperCase()/toLowerCase() - wast doing any java since last year!! - but yes you get the idea. – d-live Aug 09 '11 at 15:33
  • @Ali - Yes I agree to some extent - You can have all sorts of formatting inconcistencies in incoming text - for that you may need to write a utility function somewhere and invoke it to generate properly formatted names/variables etc. What I wanted to highlight here is that Velocity supports calling standard methods on objects just like you would do in java. So $myObj.value would be same as $myObj.getValue() if that method is defined on myObj's class. – d-live Aug 09 '11 at 15:39
  • I think the `toLowerCase()` might be removed to take profit of the velocity's case handling. I.e. `$s_attribute.name.substring(0,1).toUpperCase()` and `$s_attribute.name.substring(1)` – Vincent Pazeller Apr 03 '20 at 07:56
14

There is capitalize() method in DisplayTool. In the template you can do:

get${display.capitalize($s_attribute.name)}()

You will need the extra dependency on the classpath:

<dependency>
    <groupId>org.apache.velocity.tools</groupId>
    <artifactId>velocity-tools-generic</artifactId>
    <version>3.1</version>
</dependency>

And you need to add a the display instance to the context

    VelocityContext context = new VelocityContext();
    context.put("display", new DisplayTool());
Jmini
  • 9,189
  • 2
  • 55
  • 77
serg
  • 109,619
  • 77
  • 317
  • 330
  • Oh sweet! I saw capitalize in the API but figured it was for formatting text on the backend. This usage makes sense as well! – Ali Aug 09 '11 at 15:26
  • 1
    This `${display.capitalize(...)}` did not work for me. My output has `${display.capitalize(...)}`. Do I need to do something extra for DisplayTool to kick in? I'm using straight up vanilla velocity 1.7 – Karthic Raghupathi Aug 05 '12 at 04:54
  • 3
    @KarthicRaghupathi DisplayTool is in a separate dependency called velocity-tools. Make sure to include it and then add a DisplayTool to your VelocityContext. vc.put("display",new DisplayTool()); – AJD Dec 20 '13 at 05:21
4

If you are using commons-lang you can use the StringUtils class:

context.put("StringUtils", org.apache.commons.lang3.StringUtils.class);

Then in your template:

...
return  get$StringUtils.capitalize(s_attribute.name)();
...
naimdjon
  • 3,162
  • 1
  • 20
  • 41
  • 2
    Is there any way to do this in the VTL templates for AWS Appsync? I have no clue how to import a Class in the vtl template to call these string functions. I just want to call a capitalise function instead of writing one myself. – Mattijs May 17 '21 at 02:58
2

You could just create 2 methods getName() and getname() then when you use ${s_attribute.name} velocity will use getname() and when you use ${s_attribute.Name} velocity will use the getName() method.

From the Velocity guide:

Property Lookup Rules

As was mentioned earlier, properties often refer to methods of the parent object. Velocity is quite clever when figuring out which method corresponds to a requested property. It tries out different alternatives based on several established naming conventions. The exact lookup sequence depends on whether or not the property name starts with an upper-case letter. For lower-case names, such as $customer.address, the sequence is

getaddress()
getAddress()
get("address")
isAddress()

For upper-case property names like $customer.Address, it is slightly different:

getAddress()
getaddress()
get("Address")
isAddress()

What i'm suggesting is that you handle it in your object on the backend.

Ber
  • 40,356
  • 16
  • 72
  • 88
Ali
  • 12,354
  • 9
  • 54
  • 83