package chap10;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
/**
* A servlet that shows schedules for movie theaters in various
* cities. Supports normal web browser clients as well as WAP-enabled
* PDAs and cell phones.
*/
public class MovieServlet extends HttpServlet {
// currently supports two types of clients; could be expanded later
private static final int XHTML_CLIENT_TYPE = 1;
private static final int WML_CLIENT_TYPE = 2;
// three pages in this web app
private static final int HOME_PAGE = 100;
private static final int THEATERS_PAGE = 101;
private static final int SHOWTIMES_PAGE = 102;
/**
* This servlet supports GET and POST.
*/
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {
doPost(req, res);
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {
try {
String action = req.getParameter("action");
String city = req.getParameter("city");
String theater = req.getParameter("theater");
// default to the home page
int pageToShow = HOME_PAGE;
if ("theaters".equals(action) && city != null) {
// city is a required parameter for a theater list
pageToShow = THEATERS_PAGE;
} else if ("showtimes".equals(action) && city != null
&& theater != null) {
// city and theater are required parameters for showtimes
pageToShow = SHOWTIMES_PAGE;
}
// set the content type of the response
int clientType = determineClientType(req);
switch (clientType) {
case XHTML_CLIENT_TYPE:
res.setContentType("text/html");
break;
case WML_CLIENT_TYPE:
res.setContentType("text/vnd.wap.wml");
break;
default:
res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
File xsltFile = locateStylesheet(req, clientType, pageToShow);
// prepare for the transformation using JAXP
TransformerFactory transFact = TransformerFactory.newInstance();
Transformer trans = transFact.newTransformer(
new StreamSource(xsltFile));
// pass parameters to the XSLT stylesheet
if (city != null) {
trans.setParameter("city_id", city);
}
if (theater != null) {
trans.setParameter("theater_id", theater);
}
// all pages, both WML and XHTML, share the exact same
// XML data file
InputStream xmlIn = getServletContext().getResourceAsStream(
"/WEB-INF/xml/movies.xml");
// do the transformation
trans.transform(new StreamSource(xmlIn),
new StreamResult(res.getOutputStream()));
} catch (TransformerException te) {
throw new ServletException(te);
}
}
/**
* @param clientType one of the constants defined in this class, either
* WML_CLIENT_TYPE or XHTML_CLIENT_TYPE.
* @param pageToShow one of the _PAGE constants defined by this class.
* @return a file representing the appropriate XSLT stylesheet.
*/
private File locateStylesheet(HttpServletRequest req,
int clientType, int pageToShow) {
String xsltDir = null;
switch (clientType) {
case WML_CLIENT_TYPE:
xsltDir = "wml";
break;
case XHTML_CLIENT_TYPE:
xsltDir = "xhtml";
break;
default:
throw new IllegalArgumentException("Illegal clientType: "
+ clientType);
}
String xsltName = null;
switch (pageToShow) {
case HOME_PAGE:
xsltName = "home.xslt";
break;
case THEATERS_PAGE:
xsltName = "theaters.xslt";
break;
case SHOWTIMES_PAGE:
xsltName = "showtimes.xslt";
break;
default:
throw new IllegalArgumentException("Illegal pageToShow: "
+ pageToShow);
}
// locate a platform-dependent path
String fullPath = getServletContext().getRealPath(
"/WEB-INF/xslt/" + xsltDir + "/" + xsltName);
return new File(fullPath);
}
/**
* Determines the type of user agent.
*
* @return either XHTML_CLIENT_TYPE or WML_CLIENT_TYPE.
*/
private int determineClientType(HttpServletRequest req) {
// first check for normal web browsers that claim to be
// mozilla-compliant
String userAgent = req.getHeader("User-Agent");
if (userAgent != null
&& userAgent.toLowerCase().startsWith("mozilla")) {
return XHTML_CLIENT_TYPE;
}
// if the client accepts wml, it must be a WAP-compatible device
String accept = req.getHeader("Accept");
if (accept != null && accept.indexOf("text/vnd.wap.wml") > -1) {
return WML_CLIENT_TYPE;
}
// otherwise, default to XHTML
return XHTML_CLIENT_TYPE;
}
}
|