Search code examples
velocity

How to check if value is a map or a string in apache velocity


I use apache velocity to render templates. Now, the problem is that I have an API data feed with values that can either contain a map or a string. I iterate through the list and put values in a table. This is a sample of the feed am getting:

{
    "Secondary Camera": 
    {
        "Key1": 
        {
           "present": "true",
           "value": "2 Megapixel"
        },
        "Key2": 
        {
           "present": "true","value": "0.3 Megapixel"
        }
    }
},
{
    "Other Camera Features": 
    {
        "Key1": "Auto Focus, Panorama, Photo Sphere, Lens Blur",
        "Key2": "Panorama Shot"
    }
},  

With this the Key1/Key2 values are sometimes string and sometimes they are a map. Is there a fool proof way to make this work with strict mode on ?


Solution

  • There is a way. the main idea is to directly inspect values classes.

    The following code

    #set(
      $map = {
        'key1' : 'string_value',
        'key2' : [ 'array', 'value' ],
        'key3' : { 'map' : 'value'  }
      }
    )
    
    #set ( $obj = '' ) ## dummy object
    #set ( $string_class = $obj.class.forName('java.lang.String') )
    #set ( $map_class = $obj.class.forName('java.util.Map') )
    
    #foreach( $value in $map )
      value class name = $value.class.name
      #if ( $string_class.isAssignableFrom($value.class) )
        value is a string
      #elseif ( $map_class.isAssignableFrom($value.class) )
        value is a map
      #end
    #end
    

    will produce:

    value class name = java.lang.String
      value is a string
    value class name = java.util.LinkedHashMap
      value is a map
    

    You can also test directly if an object is a class with $obj.class.name == 'java.lang.String', but you cannot do it for maps this way, since java.util.Map is only a root abstract interface for all map classes.

    Warning: some Velocity configurations (known as secure) will forbid the access to the class property of objects.