
// EvalScript.java
// Andrew Davison, ad@coe.psu.ac.th, July 2023

/* Use dynamic Velocity scripting via the 
   Java Scripting Language Framework (JSR-223).
   https://velocity.apache.org/engine/2.3/developer-guide.html#velocity-scripting

   For another approach, see EvalTemplate.java

   Usage:
    > compile EvalScript.java
    > run EvalScript

*/

import java.io.*;
import java.util.*;
import javax.script.*;

import org.apache.velocity.app.*;
import org.apache.velocity.*;
import org.apache.velocity.script.*;


public class EvalScript 
{
  public static void main(String[] args) throws Exception 
  {
    ScriptEngineManager sem = new ScriptEngineManager();
    sem.registerEngineName("velocity", 
                       new VelocityScriptEngineFactory());

    System.out.println("Available Scripting Engines:");  // check setup
    List<ScriptEngineFactory> engines = sem.getEngineFactories();
    for(ScriptEngineFactory engine : engines)
      System.out.println(" " + engine.getEngineName());
    System.out.println();

    ScriptEngine engine = sem.getEngineByName("velocity");
    engine.put("user", "Andrew");
    engine.put("names", Arrays.asList("Jim", "Jane", "Joan", "John"));

    // dynamically create template from a string
    StringWriter sw = new StringWriter();
    engine.getContext().setWriter(sw);
    Object res = engine.eval("Hello $user\n " +
                    "#foreach ($name in $names)\n" +
                    "  $name\n" +
                    "#end\n");
    System.out.println(sw);
    System.out.println("Script result:\n" + res);  // same output as sw
  }  // end of main()

}  // end of EvalScript class