Velocity
  1. Velocity
  2. VELOCITY-444

Allow evaluation of Java expressions that does not return text or value!

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Invalid
    • Affects Version/s: 1.4
    • Fix Version/s: None
    • Component/s: Engine
    • Labels:
      None
    • Environment:
      WindowsXP

      Description

      I have started to use Velocity as a file preprocessor with my own macros in separate files. I quickly realized that there are some features missing in Velocity.

      I want to create Velocity macros with optional parameters, which is essential for my application. When a user calls my macros, she/he should not be obliged to pass all the necessary parameters to my macro. The macro should be callable with no parameter or with partial or full set of parameters. All parameters will have default values.

      I think the best way to do this is to have a Map (like a java.util.Map as in HashMap). As far as I know, Velocity does not support a Map objects directly. Such object as a Map has to be created in Java and used from the Velocity macro language. Therein lies the problem.

      Velocity does not have a reserved word for evaluating a Java expression without returning a value or text. In the documentation, using #set( $result = $myObj.method() ), method() can have side effects but it must return a value. I want to be able to call methods that return nothing (void). I have tried many things to try circumventing this but nothing works. Velocity always outputs the text of the expression without evaluating it.

      The solution would be to have a reserve construct similar like #set(....) but it would be called #eval(....). Such expression #eval(....) would take a Java expression and would evaluate it without generating any text. The #eval(....) would be used to set the value of my Map.

      // Utility Java class that creates and keeps HashMap(s)
      public static class Utility {
      public static final byte MAP_COUNT = 16;
      private final Stack<Map<String,String>> maps =
      new Stack<Map<String,String>>();

      public Utility()

      { this(MAP_COUNT); }

      public Utility(int count) {
      for(int i=0;i<count;i++)

      { maps.push(new HashMap<String,String>()); }

      }
      public Map<String,String> createMap()

      { return maps.pop(); }

      public void discardMap(Map<String,String> map)

      { map.clear(); maps.push(map); }

      }
      protected final Utility util = new Utility();

      engine.setProperty("util", util); // ...later passed as property of VelocityEngine
      ##=======================

        1. Macro to create a Map and use it inside the macro
          ##=======================
          #set( $myMap = $util.createMap() )
          $myMap.size()

      #$myMap.put("first", "alpha")
      #$myMap.put("second", "beta")
      #$myMap.put("third", "kapa")
      #$myMap.put("fourth", "gamma")
      #foreach( $myKey in [ "first", "second", "third", "fourth" ] )
      $myKey $

      {myMap.get($myKey)}
      #end

      ##=======================
      ## Output text file ...DOES NOT WORK AS PLANNED!!
      ##=======================
      $myMap.size()

      #$myMap.put("first", "alpha")
      #$myMap.put("second", "beta")
      #$myMap.put("third", "kapa")
      #$myMap.put("fourth", "gamma")
      first ${myMap.get($myKey)}

      second $

      {myMap.get($myKey)}
      third ${myMap.get($myKey)}

      fourth $

      {myMap.get($myKey)}

        Activity

        No work has yet been logged on this issue.

          People

          • Assignee:
            Unassigned
            Reporter:
            Colbert Philippe
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development