Skip to main content

B4.Execution Engine

trydoforOriginalMeepoTemplateAbout 4 min

B4.Execution Engine

The implementation and execution context of each engine is different, i.e. the scope of variables is different, and there are 2 levels, as follows

  • session level, multiple evals within a merge, in the same context, with influence on each other, e.g. js.
  • nothing level, no context associated with each eval, no influence between evals, e.g. sh depends on bash settings.

The executing engine environment, which may or may not be overwritten by the context at each eval, depends on the engine implementation.

B4.1.Dictionary Engine map

session level, each eval shares the context, and the context does not override the engine environment.

  • Take func as parameter (key), look it up in order, find non-null and return
  • The order is context,System.property,System.env,Builtin
  • key must not contain the pipe character |, or use the \ escape
  • Quotes '" in key are used as variable bounds, or escaped with \
  • Escapes like \t\r\n, otherwise, just keep the char after \

1a.Period Separated Object Navigation

Support for simple object navigation, i.e., key separated by ., there will be interference cases as follows,

  • The java System has many variables whose name contains . such as os.name, user.home
  • If the user has os or user, and use . to navigate, there will be confusion

Because of the . separated variable names, the use of environment variables in any engine implementation should follow the rules below.

During put, make sure the entire key and object navigation can be read correctly, eg.

  • Must store the entire key.
  • . separated key, store them split-by-split (map engine not implemented)

During get/use, read entire key first, if not found, read the navigation split-by-split.

  • If there is a non-null value by key, then return
  • If : exists in the key, such as out:it:name separate into out, it and name
  • Find objects recursively with out and it as object keys
    • If null is returned in any recursion, return empty string
    • If the object is Map, retrieve the value by getKey
    • Other types, retrieve by reflection, looked up Getter or Field
  • The final object in the recursion, taking name as key (map or reflection)

1b.Pipelined Functions, Chained Processing

Multiple processing functions can be piped with |, where the first one is the key and all the subsequent are function, in the following format,

key | funA | funB arg1 "arg 2"

The above equals the chain call funB(ctx, funA(ctx.get("key")), "arg1", "arg 2")

  • key - String key, can be in . seperated object navigation
    • The value of the key can be Object, Supplier<Object> or fun arg
  • fun - The first string of the pipeline syntax
    • Must be Function or JavaEval
    • function name should not use ., start with fun: recommended
    • Function.apply(obj), obj is the pipeline output or key or arg
    • JavaEval.eval(ctx, obj, arg...);
  • arg - User-defined variables, from the second string of the pipeline syntax
    • The default type of arg is a string. It can be enclosed in quotes (" or ')
    • If there are spaces in arg, they must be quoted, and the quotes inside can be escaped with \.
    • ,_ can separate number, ^([-+])?([0-9_,.]+)([DFNL]?)$
    • 1,000, 1_0000, 10,000.0, 1_0000.00 (Integer or Float)
    • Suffixes can indicate types BigDecimal(N), Double(D), Float(F), Long(L)
    • 1,000.00D,1_0000.00F,1_0000N,1_0000L
    • TRUE and FALSE are boolean type, a string type must be enclosed in quotes
    • Does not support scientific notation number

function can be set the following 3 ways,

  • Register globally with RnaManager, see built-in variable or function
  • Register to the context when merging, such as the java lambda
  • Dynamically compile and register using the RNA:PUT and fun engine
  • The registered name must start with fun: to avoid conflicts with other namespaces
  • When used, fun: can be omitted (it is recommended)

For a list of built-in functions, see Function List

1c.Built-in Variables as Follows

Meepo has few built-in variables and functions, examples of java system.property and env

  • user.name - String, current user, java built-in
  • user.dir - String, current woring dir, java built-in

Here are, the built-in date and time variables

  • now.date - String:Supplier, dynamic calculation, system date in yyyy-MM-dd
  • now.time - String:Supplier, dynamic calculation, system time in HH:mm:ss

B4.2.Output the Input raw

nothing level, return func as string directly, but return empty string when muted.

B4.3.Importing Content uri

nothing level, output the content form uri as a string in UTF8. read in then cache. Note: string type only, no parsing and dynamic execution.

  • http://,https://, read by GET request
  • file://,/, read from file system
  • classpath:, read from the classloader, Note no // here
  • Others, read by URLConnection with 3 second timeout
  • Starting with / or . means the relative path to app, but is not recommended.
  • The read content is cached in the context with uri as the key

B4.4.Direct Execution exe

nothing level, parse quoted blocks or escapes, and capture std_out output. Note: The engine overwrite environment with eval context every time.

  • exe - Execute commands directly
  • cmd - In window, execute using cmd /c
  • sh - In unix-like, execute using bash -c

B4.5.Execute js Script js

session level, run js scripts with java's ScriptEngine, capture the last evaluation result. Execute context is stored in js environment as ctx object, you can get xxx variables by ctx.xxx syntax.

For reading and writing navigation style objects in context, see to the rules of the map engine.

Note: Java 15 removed Nashorn JavaScript Engine

B4.6.Dynamic Java Code java

session level, Meepo dynamically compiles and executes Java code with context as parameter.

  • import , separated classes at head, eg. import java.util.*,java.util.Map;
  • Simple code use single line (java not simple), complex code use multi lines for readability
  • return obj at the end, and ; can be omitted
  • Dynamic compilation of Java via Java Templateopen in new window
  • The compiled java implements the pro.fessional.meepo.eval.JavaEval interface
  • Pass `RngContext ctx' for context reading
  • the following classes are already imported
    • org.jetbrains.annotations.NotNull;
    • pro.fessional.meepo.poof.impl.JavaEngine;
    • java.util.Map;

B4.7.Dynamic Java Function fun

Custom Java functions can be flexibly registered into the template engine as the follows. However, it is not recommended to use complex logic functions in templates because the templates are intended for display only.

  • Use PUT fun/ to dynamically compile the java code inside the template, then USE can execute that function.
  • Register global function via RnaManager.register
  • In the context (the Map), put the java function prefixed with fun:
  • A function registered at runtime, typically a lambda of type Function or JavaEval