Appendix: Advanced Scripting

When the basic set of attribute mappings and casters will not satisfy your requirements, Tasktop Sync can be configued to run custom scripts. This gives the administrator a very powerful tool for solving complex problems, but does require a more thorough knowledge of both Tasktop Sync and software development. This Appendix is not meant as a developer guide, but instead offers useful suggestions to help an adminstrator comfortable with basic software development.

Scipting Overview

Scripts in Tasktop Sync offer the administrator the ability to perform complex and custom data transformations during synchronizations. For example, if one system stores versions as a string, such as “Version 1-22”, and the other as a decimal, such as “1.22”, a script can be written to transform the values.

There are three types of scripts supported in Tasktop Sync, each performing a different type of transformation:

  1. Scripted Casters: Convert the content of a source attribute into the desired content for the target attribute. For example, if the source attribute may contain line feeds, but the target attribute does not allow them, a caster script could be written to remove all line feed characters.
  2. Scripted Attribute Handlers: A script is associated with a task attribute, and whenever that attribute value changes, the script is executed. These scripts can update one, or multiple attributes in the target task.
  3. Scripted Person Mappings: A script to convert the person identifier in the source repository into the associated person identifier in the target repository.

Each script is associated with a Task Attribute or Person Mapping reference, and is triggered when the associated value changes. When triggered, the script is required to calculate the changes for the target task’s attribute(s), which Sync will then apply to the target repository.

Scripts in Tasktop Sync can be written in one of two different script languages: javascript and groovy. groovy is the recommended language, and supports some features that javascript does not (as described in this appendix).

The Script Context and Lifecyle

A Groovy script goes through a small lifecyle each time it is executed:

  1. The script context is created.
  2. The script is parsed using the specified language
  3. The script is executed. This does not run the specified method, but instead defines the method(s) and declared variable(s) on the context.
  4. If defined within the script, the method setup() is executed.
  5. The primary method is excuted. The method signature is unique to the script type; for example, the scripted casters method is cast(value).
  6. If defined within the script, the method teardown() is executed.
  7. The script context is destroyed.

A script’s context contains all the methods and variables. During each execution, the context is created, the script runs through its lifecyle, and then the context is destroyed. Therefore, you cannot retain data between executions.

Retaining a Groovy Script’s Context between Executions

If you need to retain data stored on the context between executions of the script, this can be accomplished by specifying a subset of the groovy language, called groovy/concurrent.

<caster name="ConcurrentScript" language="groovy/concurrent" script="script.groovy"/>

This language offers the same Groovy language support as groovy, but its lifecyle is very different.

When the “Start” button is clicked in Tasktop Sync, the following is executed:

  1. The script context is created.
  2. The script is parsed using the specified language
  3. The script is excuted. This does not run the speicifed method, but instead defines the method(s) and declared variable(s) on the context.
  4. If defined within the script, the method setup() is executed.

Any variables defined as “script binding” variables will be retained on the script

When it is time to execute the script during a Synchronization, the following is executed:

  1. The primary method is excuted. The method signature is unique to the script type; for scripted casters, the method is “cast(value)”.

Once again, the “script binding” variables are retained after execution.

When the “Stop” button is clicked in Tasktop Sync, the following is executed:

  1. If defined within the script, the method teardown() is executed.
  2. The script context is destroyed.

A unique context is created for each point in the configuration that references a script. This means that if a single script is referenced twice in the configuration, then there will be be two unique script contexts, and they will not share their “script binding” variables.

Please note that it is up the script to handle concurrency issues. The same script context can be actively executed as the same moment by different theads, leading to unexpected results. If concurrent execution of your script is an issue, you will need to solve this using Groovy multithreading support. Please refer to Groovy language documentation for more details.

The following is an example of a groovy/concurrent script that reads a properties file once at startup. In this script, the properties file contains a property “TestValue”, which will be prepended to the attribute value during casting.

    <caster name="SampleCaster" language="groovy/concurrent"><![CDATA[
    	import java.io.FileReader;
    	import java.util.Properties;
    	import org.apache.log4j.Logger;
    	
    	properties = new Properties();
		logger = Logger.getLogger("my-groovy-script");
		
		def setup() {
			reader = new FileReader("/workspace/tasktop/my.properties");
			properties.load(reader);
			reader.close();
			logger.debug("Starting script with value "+properties.get("TestValue"));
		}

		def cast(value) {
			return properties.get("TestValue") + value;
		}

		def teardown() {
			logger.debug("Ending Script");
		}
    ]]></caster>

Logging from Scripts

Scripts in Tasktop Sync can be difficult to debug, but Tasktop Sync provides logging facilities to help with this process. To add the logging facilities in a Groovy script, ensure you import the log4j logger class in your script:

	 import org.apache.log4j.Logger
	  

Then, within your script you send messages to the logging facilities by retrieving a logger object and invoking function calls on it:

	 Logger logger = Logger.getLogger("my-groovy-script")
	 logger.error("My error message")
	 logger.debug("My debug message")
	 

Tasktop Sync’s logging facilities support fatal, error, warn, info, debug, and trace levels of logging messages.

Expanding the Groovy Classpath

When writing groovy scripts, you may want to import classes from other java libraries. For instance, you may want to communicate with your own custom server in a scripted person mapping, and you have a .jar file that can help accomplish this. Access to these libraries can be accomplished by placing the .jar library files into a folder named “dropins” in the Tasktop Sync workspace.

Before proceeding, please make note of the following:

You will need to relaunch Tasktop Sync for this to take effect. Once relaunched, the specified Java classes can then be imported into your scripts.