The high level design
of the VFCs is to simulate standard VoiceXML in Java. The behavior of these
classes directly matches the VoiceXML specifications (both versions 1 and 2).
This, however, acts only as a basis from which supporting a particular voice
browser begins, since no two browsers have exactly the same compliance. The
software provides voice browser compatibility by extending these base VFCs to
create a layer that produces the VoiceXML compatible with a particular voice
browser. Most of the functionality is still defined in the base VFC classes and
only the browser-specific functionality needs to be included in the subclasses.
The classes for a particular voice browser are encapsulated in a separate
plugin or driver, called a Gateway Adapter. Installing a new Gateway Adapter
will add support for a new voice browser and a Unified CVP application can be
deployed on a new browser by simply selecting the Gateway Adapter to use.
The design of the base
VFCs follows roughly the design of VoiceXML, utilizing similar concepts and
naming, so prior knowledge of VoiceXML is beneficial for understanding the VFC
design. The VFCs allow full compatibility with VoiceXML in that anything you
can do in VoiceXML you can do in the VFCs, including using proprietary tags
and/or attributes introduced by supported browsers.
Many times, a single
VoiceXML tag maps to a single VFC that is similarly named. The class
for example, deals with VoiceXML
<form> tags and the class
<field> tags. Some tags, however, have been
combined into a single VFC for ease of use. For example, the
VAction class encapsulates tags from
<submit>. As a result, there are fewer VFCs than
VoiceXML tags. The VFCs also help the developer by producing some VoiceXML
automatically. The developer will quickly find that using the VFCs is very much
like coding in VoiceXML, except in Java.
There are a few
concepts that need to be described before delving into the individual VFCs.
First, each VFC class extends a common base class,
The purpose for this is similar to having all Java classes extend
Object, it is a way to help define common functionality
of the VFCs as well as being able to identify if a Java class is a VFC.
The second concept
involves the hierarchy of the VFCs. There are, in fact, several layers of
abstraction in the VFCs that separate not only differences between various
voice browsers but also versions of the VoiceXML standard. There are separate
VFCs for VoiceXML version 1.0 and version 2.0, and the similarities are
encapsulated in a common base class. The following figure, shows this
graphically with the
class. The main
class extends the
class and is itself extended by
VFormV2, representing VoiceXML 1.0 and 2.0 compliances.
Luckily, there are only a few differences between these versions, so the
developer can still do most coding to the base
class. The Gateway Adapters introduce VFCs that extend
VFormV2 depending on whether the voice browser it
supports is compatible with VoiceXML 1.0 or 2.0.
Figure 1. VForm and Its
The last concept is
that VFC objects are not instantiated using the
keyword. A static factory method named
is used instead. The reason for this is related to the abstraction of the voice
browser differences. As mentioned previously, a developer need only code using
the base VFC classes. At runtime, the factory methods used to instantiate VFC
classes actually returns the appropriate voice browser-specific VFC (for
VFormFoo in the illustration). But since the developer
treats the return object as the base VFC, that object is downcasted. This is
the heart of the VFC abstraction design. Since all VFC derivative classes
extend their base VFCs, a developer need only code to the base VFCs and that
automatically makes their code compatible with any voice browser represented by
a Gateway Adapter.
In order to identify
which voice browser VFC to return, every factory method must include as its
first argument an instance of
VPreference, while a VFC class, does not match to a
VoiceXML tag, it is used instead to hold preferences made by the user in
Builder for Call Studio for the application, such as the voice browser and
default audio path. By passing this object to all factory methods, the
appropriate object can be returned. The
VPreference instance is automatically created for the
developer and made available through the Session API passed to voice elements,
hotevents, or call end classes.
The following Java
code demonstrates the concepts described above:
VPreference pref = ved.getPreference();
VForm form = VForm.getNew(pref, "start");
VPreference object is obtained from the
VoiceElementData object passed as input to a voice
element. It is used to create a
object. Assuming the application is using the voice browser Foo, that choice is
reflected in the
VPreference object and therefore the
factory method returns a
VFormFoo object, which is automatically downcasted to a
object. The developer then uses the form object as desired.
This ability to treat
all objects returned as a root VFC object is not available when the developer
wishes to use functionality that exists either in a particular version of
VoiceXML or a particular voice browser. The developer must understand that
doing so would prevent their code from functioning on all voice browsers. In
this case, the developer simply treats the return of the factory method as a
class higher in the class hierarchy (VFormV2 or
VFormFoo in the illustration).
The following Java
code demonstrates this:
VGrammar myGrammar = VGrammar.getNew(pref);
setMaxage method exists only in the
VGrammarV2 class since this is a feature that exists
only in VoiceXML 2.0. To call this method, one must first upcast the previously
downcasted object back to VGrammarV2. If this is not done, an exception will be
thrown indicating that
VGrammar does not have a method named
If the user in the
Builder chose a voice browser that was compatible with VoiceXML 1.0 only, a
runtime exception would be thrown when this code is encountered because that
browser would be unable to understand VoiceXML referring to maxage.