Listing 3 [DirectoryServlet] /*==========================================================================* * Copyright © 1999-2001 by Bluestone Software, Inc. All rights Reserved. * *==========================================================================* * $Archive $ * $Revision: $ * $Date: $ * $Author: $ *==========================================================================*/ package com.hp.mw.mobile.samples.voice.airlineDirectory.servlets; import com.hp.mw.mobile.samples.voice.airlineDirectory.DirectoryHome; import com.hp.mw.mobile.samples.voice.airlineDirectory.Directory; import com.hp.mw.mobile.samples.voice.airlineDirectory.DirectoryPK; // EJB stuff import javax.naming.InitialContext; import javax.naming.Context; import javax.naming.NamingException; import java.rmi.RemoteException; import javax.ejb.FinderException; import javax.rmi.PortableRemoteObject; // Servlet stuff import javax.servlet.http.HttpServlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Hashtable; // XTF stuff import com.hp.mw.xtf.XTF; import com.hp.mw.xtf.XTFFactory; import java.util.StringTokenizer; import java.util.ResourceBundle; /** * Handler servlet for voice requests. This class brokers the remote * interface and deals with the entity bean. It also requests the * transformer to create dynamic voiceXML for output. * * @author Lionel Lavallee */ public class DirectoryServlet extends HttpServlet { /** * This is the URL of the transformation XML configuration file for the XTF */ String m_transformationXMLFile = null; /** * This is the debug setting for the XTF */ boolean m_debugXTF = false; /** Creates new DirectoryServlet */ public DirectoryServlet() { } /** * The init method. This method reads configuration from a ResourceBundle. * */ public void init() throws ServletException { //get the location of the transformation XML configuration file for the XTF. m_transformationXMLFile = getInitParameter( "transformationXMLURL" ); System.out.println( m_transformationXMLFile ); //get the debug setting for the XTF String debug = getInitParameter( "debug" ); if( debug.equalsIgnoreCase( "true" ) ) { m_debugXTF = true; } else { m_debugXTF = false; } } /** * doPost: called by the servlet container when recieving a request * * @param request the request object * @param response the response object * * @throws IOException * @throws ServletException */ public void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { } /** * doGet: returns Dynamic VoiceXML to caller * * @param request * @param response * * @throws IOException * @throws ServletException */ public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { int id = 0; String formattedText = ""; // get the number from the parameters //String idString = request.getParameter( "namelist" ); String queryString = request.getQueryString(); String idString = "0"; StringTokenizer st = new StringTokenizer( queryString, "=" ); while( st.hasMoreTokens() ) { // the last one is the one we want, so let it overwrite idString = ( st.nextToken() ); } // make sure there's something in the damn thing... if( idString != null ) { id = new Integer( idString ).intValue(); } String numberText = getNumber( id ); formattedText = Formatter.getVoiceXML( numberText ); // now do the transformation by first getting an instance of the XTF XTF xtf = XTFFactory.getInstance( m_transformationXMLFile, m_debugXTF ); /* now we need to build the action XML document that lets the XTF know what type of transformation sequence to run invoke. NB, in a multi client, MVC application, the value of the name attribute and type node would be set dynamically. */ String actionXML = "directory-servlet"; /* then invoke the transformation and pass the response object so that the transformation objects can set the HTTP response content type for us as required. The returned String is passed to the Servlet PrintWriter. */ String output= xtf.transform( formattedText, actionXML, response ); response.getWriter().print( output ); } /** * Gets the string version of the airline telephone number * * @param id The id of the airline selected. * * @return String of the telephone number for Text To Speech engines */ private String getNumber( int id ) { String number = "Result error: number not retrieved"; Directory directory = getRemoteInterface( id ); try { number = directory.getNumber(); } catch( RemoteException re ) { re.printStackTrace(); } return number; } /** * Allows reusage of the remote interface. This method does the JNDI lookup * on our home object. * * @param id The Id of the selected airline - necessary for the primary key class * * @return */ private Directory getRemoteInterface( int id ) { Directory directory = null; try { Context jndiContext = getInitialContext(); Object ref = jndiContext.lookup( "sapphire://DirectoryHome" ); DirectoryHome home = (DirectoryHome)PortableRemoteObject.narrow( ref, DirectoryHome.class ); DirectoryPK primKey = new DirectoryPK( id ); directory = home.findByPrimaryKey( primKey ); } catch( RemoteException re ) { re.printStackTrace(); } catch( NamingException ne ) { ne.printStackTrace(); } catch( FinderException fe ) { fe.printStackTrace(); } return directory; } /** * Sets the context data member through the Naming service * * * @return * @throws NamingException */ private Context getInitialContext() throws NamingException { Hashtable envHashtable = new Hashtable(); envHashtable.put( Context.URL_PKG_PREFIXES, "com.bluestone.jndi" ); Context jndiContext = new javax.naming.InitialContext( envHashtable ); return jndiContext; } } [Formatter.java] package com.hp.mw.mobile.samples.voice.airlineDirectory.servlets; /** * * @author lilava * @version */ public class Formatter extends java.lang.Object { /** * This is a convenience class that I created to bypass the database. Had some real time constraints and * didn't have the time to get the container working on Joe's machine. This class holds a quick lookup * for the realy data. It should be removed and the formatting string END_XML added to the servlet. * EJB stuff has been verified and tested on several other environments. Go figure. */ public Formatter() { } /* This is old stuff -- remove after a month or so... //static String BEGIN_XML = "
";//""; //static String END_XML = "
";//"";// */ /* If you're using EJB, then IT will add the first parts, we'll need to add the next destination. Also this will need to be moved into the servlet, since it knows where to next... static String END_XML = ""; */ // XML tags for the required string static String BEGIN_XML = ""; static String MID_XML = ""; static String END_XML = ""; public static String getVoiceXML( String text ) { // StringBuffers are much more performance friendly StringBuffer formattedXML = new StringBuffer(); /* These tags will create a well formed XML doc for the XTF of the form: The number for America West is 1, 800... firstGroupSel.vxml#selectAL This functionality should be moved to the DirectoryBean class when we finally wish to utilize them. The bean will know how to format its data. */ formattedXML.append( BEGIN_XML ). append( text ). append( MID_XML ). append( "firstGroupSel.vxml#selectAL" ). append( END_XML ); return formattedXML.toString(); } }