This chapter provides an introduction to the Script bus and describes how scripting engines other than JavaScript can be integrated into VoiceObjects and utilized in the Script object.
The VoiceObjects platform comes with a JavaScript 1.5 engine that is used to process JavaScript code provided in Script objects. In case a different script engine is required for a project, you can add a description of this engine and an interface definition to the VoiceObjects configuration. Within each Script object the engine can then be selected individually.
Three separate steps are necessary to add a new script engine to the Script bus. In the first step, the configuration files for VoiceObjects Desktop and VoiceObjects Server need to be adapted. Next, a custom XML file that defines the interface to the script engine has to be created. Finally, the corresponding Java code must be provided, which defines how to call the script engine and how to pass data to it. The next paragraphs describe in detail how to perform these steps.
Before a custom script engine can be used within a Script object, it has to be configured for VoiceObjects Desktop and VoiceObjects Server. This is done by defining the element <ScriptLibraries> in the files Eclipse_Configuration.xml (only when using Desktop for Eclipse), VODesktop_Configuration.xml (only when using Desktop for Web) and VOServer_Configuration.xml.
The configuration file Eclipse_Configuration.xml is located in the folder
…plugins/com.voiceobjects.eclipseDesktop_9.1.0/config
whereas VODesktop_Configuration.xml and VOServer_Configuration.xml are located in the folder …/VoiceObjects/Platform/WEB-INF/config:
<ScriptLibraries>
<ScriptLibrary>VisualComposerScript.xml</ScriptLibrary>
</ScriptLibraries>
The custom XML definition file referenced in <ScriptLibrary> can be any file ending in .xml that has the structure described in the next paragraph. There can be any number of <ScriptLibrary> elements below <ScriptLibraries>.
The custom XML definition file is the interface between the VoiceObjects platform and the custom Java interface implementation. It must be located in the folder …plugins/com.voiceobjects.eclipseDesktop_9.1.0/config (Desktop for Eclipse) and in the folder …/VoiceObjects/Platform/WEB-INF/config of your VoiceObjects installation. Within this file, a script engine is described by an XML structure that consists of two parts, Header and ScriptEngine. The root element is <ScriptLibrary>. For an example of such a file, see XML Definition Example.
The <header> element holds general information about the script engine definition, such as the path to documentation files.
Example:
<header>
<defaultLocaleID>en</defaultLocaleID>
<namePrefix>
<locale id="en">ScriptType -&nsbp;</locale>
<locale id="de">SkriptTyp -&nsbp;</locale>
</namePrefix>
<docPath>http://myPC/docs/customScript/doc/</docPath>
</header>
i8 Note: VoiceObjects Desktop currently supports different locales for en (English) and de (German).
|
Tag |
Description |
|
<defaultLocaleID> |
The locale that is used by default when displaying information in VoiceObjects Desktop. |
|
<namePrefix> |
The prefix for the script engine name, which is displayed in the Script editor in VoiceObjects Desktop and may differ for different locales. |
|
<docPath> |
Contains a generic path, which will be concatenated with the specific <docFile> settings for each script engine defined. |
The <ScriptEngine> element holds the actual script engine definition.
|
Tag |
Description |
|
<id> |
The ID of the script engine in the metadata of the Script object. It is mandatory and needs to be unique. |
|
<name> |
Inside the <name> tag different names can be defined for different languages (locales). The defined name of the active locale is shown in the Type field of the Script editor in VoiceObjects Desktop. If the tag <namePrefix> was defined before, a concatenation of <namePrefix> and <name> is shown in VoiceObjects Desktop. |
|
<description> |
Inside the <description> tag different descriptions can be defined for different languages (locales). The defined description of the active locale is displayed in the description field below the Type field in the Script editor in VoiceObjects Desktop. |
|
<docFile> |
Inside the <docFile> tag different documentation files together with an optional HTML reference can be defined for different languages (locales). This value is interpreted relative to the defined <docPath>. In Desktop for Web the defined HTML file of the active locale is linked to the question mark button next of the Type field in the Script editor in VoiceObjects Desktop. |
|
<source> |
A comma-separated list of JAR files holding the Java classes that implement the interface to the script engine. |
|
<location> |
The location path of the JAR files. Can either be an absolute path, or one that is relative to the directory that the XML file is stored in. |
|
<class> |
The name of the Java class implementing the interface to the script engine factory. |
|
<persistenceLevel> |
One of server, service, dialog, and none. Defines whether the instance of the script engine is to be persisted, either at dialog, service or server instance level: None Dialog Service Server Instance |
|
<configuration> |
Holds none, one, or more <parameter> elements that define script-specific configuration parameters to be passed over to the script engine. Each <parameter> element needs a name attribute specifying the configuration parameter name and can hold an arbitrary value for this parameter. |
The following code shows an example definition to attach SAP's Visual Composer Script to the Script bus.
<?xml version="1.0" encoding="UTF-8"?>
<ScriptLibrary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../schemas/ScriptLibrary.xsd">
<header>
<defaultLocaleID>en</defaultLocaleID>
<namePrefix>
<locale id="en">ScriptType -&nbsp;</locale>
</namePrefix>
<docPath>http://intra/docs/ThirdParty/SAP/
Script/Doc/
</docPath>
</header>
<ScriptEngine>
<id>sap</id>
<name>
<locale id="en">Visual Composer Script</locale>
</name>
<description>
<locale id="en">The script resource is expected to be
Visual Composer Script code, which is
interpreted by VoiceObjects Server.
</locale>
</description>
<docFile>
<locale id="en">Custom help file path</locale>
</docFile>
<source>SampleScript.jar</source>
<location>../WEB-INF/script_lib/</location>
<class>com.voiceobjects.sample.
SampleScriptEngineFactoryImpl
</class>
<!-- Valid Types are server,service,dialog,none -->
<persistenceLevel>server</persistenceLevel>
<configuration>
<parameter name="initialParams">paramvalue1,
paramvalue2
</parameter>
</configuration>
</ScriptEngine>
</ScriptLibrary>
The following code snippets show an example for a script engine implementation. The first code snippet provides a sample of a factory that creates the script engines, while the second one defines the script engine that is executed when the script is processed through a Script object.
The SampleScriptEngineFactoryImpl only creates the ScriptEngine.
package com.voiceobjects.sample;
import com.voiceobjects.scripting.ScriptEngineException;
import com.voiceobjects.scripting.VODialogContextFunctions;
import com.voiceobjects.scripting.VOScriptingEngine;
import com.voiceobjects.scripting.VOScriptingEngineFactory;
import java.util.Map;
public class SampleScriptEngineFactoryImpl implements VOScriptingEngineFactory
{
/**
* Creates new script engine based on the connection params.
*
* @param functions VO Dialog Context functions can be passed.
* @return scripting engine to be used for evaluation of script.
*/
public VOScriptingEngine createScriptEngine( final Map connectionParams, final VODialogContextFunctions functions )
throws ScriptEngineException
{
String initialParam = "empty";
if ( null != connectionParams && connectionParams.containsKey( "initialParams"))
{
initialParam = (String)connectionParams.get( "initialParams");
}
final SampleScriptEngineImpl sampleScriptEngine = new SampleScriptEngineImpl( initialParam, functions );
return sampleScriptEngine;
}
}
The execute method of the ScriptEngine is executed when the Script object is processed. A string is returned as the result of the execute method and this string contains the evaluation results of the passed dialog context functions:
package com.voiceobjects.sample;
import com.voiceobjects.scripting.ScriptEngineException;
import com.voiceobjects.scripting.VOScriptingEngine;
import com.voiceobjects.scripting.VODialogContextFunctions;
import java.util.Map;
public class SampleScriptEngineImpl implements VOScriptingEngine
{
private String _initialParam;
private VODialogContextFunctions _functions;
public SampleScriptEngineImpl( final String initialParam,
final VODialogContextFunctions contextFunctions)
{
_initialParam = initialParam;
_functions = contextFunctions;
}
/**
* Executes the script provided, altering parameter values upon return. Method does not add new keys to parameters.
* May connect to a business service, get/set variables, and/or evaluate expressions.
*
* @param script A script, as specified in the VoiceObjectsXML, passed by VoiceObjects through to the script
* engine.
* @param parameters Maps VoiceObjects variable names to values. Values may be null (e.g., if the value is not
* initialized).
* @return Result of the script, if any (may be null).
*/
public String execute( final String script, final Map parameters ) throws ScriptEngineException
{
final StringBuffer buffer = new StringBuffer( );
buffer.append( "Intial Param " + _initialParam + " script resulted in " + script).append( " ");
buffer.append( "abs :" + _functions.abs("-9.8"));
buffer.append( "and " + _functions.and("false","true")).append( " ");
buffer.append( "ani " + _functions.ani( )).append( " ");
buffer.append( "bargein " + _functions.bargein( )).append( " ");
buffer.append( "between " + _functions.between( "10", "10", "25")).append( " ");
buffer.append( "ceil " + _functions.ceil("9.8146" )).append( " ");
buffer.append( "channel " + _functions.channel( )).append( " ");
buffer.append( "databaseType " + _functions.databaseType( "systemDB")).append( " ");
buffer.append( "databaseURL " + _functions.databaseURL( "systemDB")).append( " ");
buffer.append( "dnis " + _functions.dnis()).append( " ");
buffer.append( "driver " + _functions.driver()).append( " ");
buffer.append( "driverASREngine " + _functions.driverASREngine()).append( " ");
buffer.append( "driverProductName " + _functions.driverProductName()).append( " ");
buffer.append( "driverProductVersion " + _functions.driverProductVersion()).append( " ");
buffer.append( "driverVendorName " + _functions.driverVendorName()).append( " ");
buffer.append( "driverVXMLVersion " + _functions.driverVXMLVersion()).append( " ");
buffer.append( "encoding " + _functions.encoding()).append( " ");
buffer.append( "errorCode " + _functions.errorCode()).append( " ");
buffer.append( "errorMessage " + _functions.errorMessage()).append( " ");
buffer.append( "eventCounter " + _functions.eventCounter("noinput")).append( " ");
buffer.append( "eventCounter" + _functions.eventCounter("noinput","global" )).append( " ");
buffer.append( "eventList " + _functions.eventList()).append( " ");
buffer.append( "eventList " + _functions.eventList("global" )).append( " ");
buffer.append( "exitEvent " + _functions.exitEvent( )).append( " ");
buffer.append( "find " + _functions.find("World","Hello World", "1" )).append( " ");
buffer.append( "floor " + _functions.floor( "9.8146")).append( " ");
buffer.append( "grammarType " + _functions.grammarType("srgs-xml")).append( " ");
buffer.append( "grammarType " + _functions.grammarType()).append( " ");
buffer.append( "in " + _functions.in("Smith, John", "Smith, John, Miller, Mary","")).append( " ");
buffer.append( "inputMode " + _functions.inputMode()).append( " ");
buffer.append( "insert " + _functions.insert( "Hello ","7","World")).append( " ");
buffer.append( "isLogical " + _functions.isLogical( "true")).append( " ");
buffer.append( "isNumber " + _functions.isNumber("test")).append( " ");
buffer.append( "isText " + _functions.isText("test")).append( " ");
buffer.append( "language " + _functions.language("en-US")).append( " ");
buffer.append( "language " + _functions.language( )).append( " ");
buffer.append( "lastResult " + _functions.lastResult("length" )).append( " ");
buffer.append( "lastResult " + _functions.lastResult( "length","0")).append( " ");
buffer.append( "lastTransition " + _functions.lastTransition("mode")).append( " ");
buffer.append( "ln " + _functions.ln( "1")).append( " ");
buffer.append( "lower " + _functions.lower("voIceServer" )).append( " ");
buffer.append( "ltrim " + _functions.ltrim("$$$Hello$ztr$","$" )).append( " ");
buffer.append( "mid " + _functions.mid("Hello", "2", "3" )).append( " ");
buffer.append( "moduleHistory " + _functions.moduleHistory()).append( " ");
buffer.append( "moduleHistory " + _functions.moduleHistory("1")).append( " ");
buffer.append( "moduleRefID " + _functions.moduleRefID()).append( " ");
buffer.append( "moduleRefID " + _functions.moduleRefID("0" )).append( " ");
buffer.append( "moduleSet " + _functions.moduleSet()).append( " ");
buffer.append( "moduleSet " + _functions.moduleSet( "1")).append( " ");
buffer.append( "nand " + _functions.nand("false","true")).append( " ");
buffer.append( "nor " + _functions.nor("false","true" )).append( " ");
buffer.append( "not " + _functions.not( "false")).append( " ");
buffer.append( "notbetween " + _functions.notbetween( "5", "25.0", "10.0")).append( " ");
buffer.append( "or " + _functions.or( "true","false")).append( " ");
buffer.append( "outputMode " + _functions.outputMode()).append( " ");
buffer.append( "outputMode" + _functions.outputMode( )).append( " ");
buffer.append( "pow" + _functions.pow("10","2")).append( " ");
buffer.append( "projectInfo" + _functions.projectInfo("project" )).append( " ");
buffer.append( "replace " + _functions.replace("Hello World", "7", "5", "London")).append( " ");
buffer.append( "round " + _functions.round("9.8146","2" )).append( " ");
buffer.append( "rtrim " + _functions.rtrim("$$$Hello$ztr$","$" )).append( " ");
buffer.append( "serverContextMappingURL " + _functions.serverContextMappingURL()).append( " ");
buffer.append( "serverHostIP " + _functions.serverHostIP()).append( " ");
buffer.append( "serverHostname " + _functions.serverHostname()).append( " ");
buffer.append( "serverName " + _functions.serverName()).append( " ");
buffer.append( "serverPort " + _functions.serverPort()).append( " ");
buffer.append( "serverServletContext " + _functions.serverServletContext()).append( " ");
buffer.append( "serverURL " + _functions.serverURL()).append( " ");
buffer.append( "sessionVariable " + _functions.sessionVariable("myvar","myvalue" )).append( " ");
buffer.append( "sessionVariable " + _functions.sessionVariable("myvar" )).append( " ");
buffer.append( "sessionVariable " + _functions.sessionVariable( "ani")).append( " ");
buffer.append( "sign " + _functions.sign("-9.8" )).append( " ");
buffer.append( "snmpTrap " + _functions.snmpTrap("send trap")).append( " ");
buffer.append( "trim " + _functions.trim( "Hello ")).append( " ");
buffer.append( "trunc " + _functions.trunc("9.8146","2" )).append( " ");
buffer.append( "upper " + _functions.upper( "voIceServer")).append( " ");
buffer.append( "visitCounter " + _functions.visitCounter( "ExternalScript")).append( " ");
buffer.append( "xor " + _functions.xor("true", "false")).append( " ");
return buffer.toString();
}
/**
* Releases all resources associated with this instance (locally and if necessary remotely). The instance is no
* longer usable after this method is called.
*/
public void destroy()
{
final String destroy = "DESTROY";
_functions = null;
}
public void setInitialParam( final String initialParam )
{
_initialParam = initialParam;
}
}
The script engine can be selected in the Script object. The name and description of the engine are taken from the configuration file:
