FileDocCategorySizeDatePackage
MovieServlet.javaAPI DocExample5667Sun Sep 02 14:59:02 BST 2001chap10

MovieServlet.java

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;
    }
}