Package scriptella.driver.script


package scriptella.driver.script

Scriptella bridge for the JSR 223: Scripting for the Java Platform.

Allows usage of JSR 223 compatible scripting languages in ETL <query> and <script> elements.

The driver uses the Java SE javax.script API. The default language name is JavaScript. Scriptella distributions bundle Mozilla Rhino; JEXL also remains available out of the box.

General information

Driver class:scriptella.driver.script.Driver
URL:URL of the file to read from and send output to. URIs are resolved relative to a script file. If url is not specified console (System.in/out) is used.
Runtime dependencies:Additional dependencies are specific to a scripting language.

Driver Specific Properties

Name Description Required
language Language used in scripts and queries. No, the default language is JavaScript.
encoding Specifies charset encoding of a character stream specified by an url connection parameter. No, the system default encoding is used.

Query and Script Syntax

This driver executes code through a JSR-223 script engine. The selected engine defines the language syntax.

A script runs once when reached. A query produces rows, and its nested elements run once for every produced row. Scripts and queries can reference variables from ancestor elements.

Script-based queries produce a row explicitly. The implicit query variable is available inside a <query>; calling query.next() exposes the current script variables to the nested elements, runs those elements once, and then resumes the query script. Database, CSV, and other row-producing drivers advance their queries themselves and do not require query.next() in ETL content.


    <query><![CDATA[
        var v1 = 'This variable is visible in a child script';
        for (var i = 0; i < 3; i++) {
            query.next(); // Runs the nested script for the current row.
        }]]>
        <script>
            Current values are ${i} and ${v1}
        </script>
    </query>

See ParametersCallbackMap class Javadoc for more details.

JavaScript provider

On JDK 17, JavaScript requires a JSR-223 provider. Scriptella's binary and examples distributions include Mozilla Rhino 1.9.1 as separate lib/rhino-engine.jar and lib/rhino.jar files. Keep the distribution intact when using java -jar scriptella.jar, bin/scriptella.sh, or bin/scriptella.bat.

Maven applications add org.mozilla:rhino-engine:1.9.1, which brings the matching org.mozilla:rhino:1.9.1 runtime.

Embedded applications must make the provider visible to the same application classloader as Scriptella's script driver. A script connection's classpath attribute is not used for JSR-223 provider discovery.

Example of the connection declaration:

    <connection driver="script">
        language=rhino
    </connection>
The aliases js, JS, javascript, JavaScript, ecmascript, and ECMAScript also use Rhino when their primary engine lookup does not resolve another provider.

Examples

The script driver defaults to JavaScript. The following query produces three rows. Each call to query.next() runs the nested text script with the current values of i and name:
<connection id="script" driver="script"/>
<connection id="console" driver="text"/>

<query connection-id="script">
    <![CDATA[
    for (var i = 0; i < 3; i++) {
        name = 'row-' + i;
        query.next();
    }]]>
    <script connection-id="console">
        ROW_${i}=${name}
    </script>
</query>

Advanced example: Script variables and Java objects created by a query are also available to its nested scripts. This variation uses Java MessageFormat and reflection to write a formatted message to log.txt for every produced row:

<connection id="script" driver="script"/>
<connection id="log" driver="script" url="log.txt"/>

<query connection-id="script">
    <![CDATA[
    var format = new java.text.MessageFormat('Row {0}: {1}');
    for (var i = 0; i < 3; i++) {
        name = 'row-' + i;
        query.next();
    }]]>

    <script connection-id="log">
        // Build the Object[] expected by MessageFormat.format().
        var values = java.lang.reflect.Array.newInstance(java.lang.Object, 2);
        values[0] = i;
        values[1] = name;
        println(format.format(values));
    </script>
</query>