4

I use Telosys (https://www.telosys.org) to generate Python source code and it works fine. But I have a specific need that could be solved by calling a specific conversion function.

Is it possible to create a specific function and to call it inside a Telosys template?

For example: myFunction(“abc”) or $something.myFunction(“abc”) or anything else

If necessary it's possible for me to create this function in different languages ​​like Java, Python or JavaScript.

JackPat99
  • 232
  • 1
  • 10

1 Answers1

4

Telosys is designed to be extensible, so yes you can create your own functions and call them in your templates. As Telosys is written in Java you will have to create these functions in Java, then use the "loader" object in the ".vm" file to load your class and call the methods defined in this class.

Here's how to do that step by step:

  1. Use your preferred IDE to create a Java class defining your specific method(s). This class can be in any package (including the "default / unnamed package"), the method(s) can be "static" if you don't need an instance of the class.

  2. Compile this class (the goal is to produce a simple ".class" file or a ".jar" file if you prefer)

  3. Put the class (or the jar) in the templates bundle folder :

  • if you have a ".class" file put it in "classes" folder
  • if you have a ".jar" file put it in the "lib" folder

Examples :

TelosysTools/templates/my-bundle/classes/MyClass.class
TelosysTools/templates/my-bundle/lib/my-lib.jar
  1. In the template file (".vm") use the "$loader" object to load your Java class and call any of its methods See "$loader" reference here : http://www.telosys.org/templates-doc/objects/loader.html

If all your methods are “static” you don’t need an instance so just use “$loader.loadClass()”. Example :

## load the class and keep it in a new “$Math” object (no instance created)
#set( $Math = $loader.loadClass("java.lang.Math")
## use the static methods of this class
$Math.random()

If your methods are not “static” so you need an instance, then use “$loader.newInstance()”. Examples :

## create an instance of StringBuilder and put it in the context with #set
#set( $strBuilder = $loader.newInstance('java.lang.StringBuilder') )
## use the instance to call a method
$strBuilder.append('aa')
       
## create new instance of a specific class : MyTool.class
#set( $tool = $loader.newInstance('MyTool') )
## use the instance to call a method
$tool.myFunction()

So to sum up, you can use any class provided by Java-JRE (eg "Math", “StringBuilder”), you can reuse existing libraries by adding a “.jar” file (don't forget to add dependencies required if the jar file is not stand-alone) or just add a single “.class” file.

lgu
  • 2,342
  • 21
  • 29
  • 3
    There are class loading examples in the "advanced-templates-samples" templates bundle : https://github.com/telosys-templates-v3/advanced-templates-samples-T300, See templates "loader_examples.vm" and "loader2_examples.vm" (java classes sources are also provided in the bundle in "classes" folder). – rlopez Aug 19 '20 at 10:15
  • 1
    I might add that you can also define Velocity macros using #macro from inside the Velocity templates, without any Java code. It is sometimes useful. – Claude Brisson Aug 19 '20 at 12:16
  • Yes, if a Velocity macro is sufficient for what you want to do it's the simplest way. If the processing to be performed is more complex you will have to implement it in a Java class. – lgu Aug 19 '20 at 12:33
  • Velocity macro doc : https://velocity.apache.org/engine/1.7/user-guide.html#velocimacros https://www.telosys.org/templates-doc/velocity/macro.html NB : macro are not functions but you can retrieve the result as text https://stackoverflow.com/questions/6914312/calling-macro-function-in-velocity-template – lgu Aug 19 '20 at 12:42
  • Thank you all. My conversion is quite complex, so I've created a Java class as mentioned in the response and it works perfectly. Bonus: I can test my function with JUnit :-) – JackPat99 Aug 19 '20 at 14:39