Your class should override onCreateRunner and onInitRunner to do additional initialization, such as:
- create and attach a model object
- register prompt file(s)
- set the extension point factory
- other things. For example, the SimpsonsDemo app records votes in a text file, and its Voting object needs to be initialized with the path
public SRRunner createRunner(String projectDir, String returnUrl, String baseUrl, ISRServlet servlet);
The projectDir is a path to the application's base directory, which usually has sub-directories audio, grammar, and sro.
The two URLs are only needed in a servlet environment. returnUrl is the URL that the VoiceXML page should postback to. baseUrl is used to generate URLs for audio and grammars.
servlet can be null. It's an extension point that allows the servlet to do extra initialization.
Now let's look at each environment in turn.
JUnit
In a unit test, the dependencies can be visualized like this, from top to bottom:
JUnit test class
App (your callflow)
SRRunner
SRFactory or your derived class
SRConfig
Use your app factory to create a runner
AppFactory factory = new AppFactory();Then run your application using the start and proceed methods of SRRunner.
SRRunner run = factory.createRunner();
If your app uses properties in the srf.properties file, you need to initialize SRConfig first. JUnit 4 has a per-class initializer called @BeforeClass
@BeforeClass static public void redirectStderr() {
SRConfig.init("C:\\source\\app2\\", "srf.properties");
}
Interactive tester
The interactive tester is a console app. It's The dependencies can be visualized like this, from top to bottom:
App (your callflow)
SRInteractiveTester
SRRunner
SRFactory or your derived class
SRConfig
SRInteractiveTester inits SRConfig for you.
SRInteractiveTester tester = new SRInteractiveTester();
AppFactory factory = new AppFactory();
SRRunner runner = factory.createRunner(appDir, "http://def.com", "", null);
App app = new App();
tester.init(app, run);
tester.run();
Servlet
In a servlet, the dependencies can be visualized like this, from top to bottom:
Servlet
App (your callflow)
SRRunner
SRServletRunner
SRFactory or your derived class
SRConfig
In a servlet the SRServletRunner class is used. You pass your app factory and it does initialization, including SRConfig. The SRRunner's project directory is set to the directory corresponding to the web apps' "/" url.
The code in doGet should be
SRServletRunner runner = new SRServletRunner(new AppFactory(), null, request, response, "GET");
if (runner.isNewSession()) {
SRRunner run = runner.createNewSRRunner(this);
IFlow flow = new App();
runner.startApp(flow);
}
else {
runner.continueApp();
}
The code in doPost should be
SRServletRunner runner = new SRServletRunner(new AppFactory(), null, request, response, "POST");
if (runner.isNewSession()) {
//err!!
runner.log("can't get new session in a POST!!");
}
else {
runner.continueApp();
}
SRConfig
SRConfig provides access to an srf.properties file. Properties are often used by the constructors of flow objects. Therefore it's important to initialize SRConfig early:
SRConfig.init(path, "srf.properties");
For console apps or JUnit, a hard-coded path is used. For servlets, this is done for you by SRServletRunner, which uses the directory corresponding to the web app's "/" base url.
Currently the SpeakRight framework itself does not use any properties, but applications are free to.