package com.oreilly.jent.people.servlet;

/**
 * In general, you may use the code in this book in your programs and 
 * documentation. You do not need to contact us for permission unless 
 * you're reproducing a significant portion of the code. For example, 
 * writing a program that uses several chunks of code from this book does 
 * not require permission. Selling or distributing a CD-ROM of examples 
 * from O'Reilly books does require permission. Answering a question by 
 * citing this book and quoting example code does not require permission. 
 * Incorporating a significant amount of example code from this book into 
 * your product's documentation does require permission.
 * 
 * We appreciate, but do not require, attribution. An attribution usually 
 * includes the title, author, publisher, and ISBN. For example: 
 * 
 *   "Java Enterprise in a Nutshell, Third Edition, 
 *    by Jim Farley and William Crawford 
 *    with Prakash Malani, John G. Norman, and Justin Gehtland. 
 *    Copyright 2006 O'Reilly Media, Inc., 0-596-10142-2."
 *  
 *  If you feel your use of code examples falls outside fair use or the 
 *  permission given above, feel free to contact us at 
 *  permissions@oreilly.com.
 */

import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Logger;

import javax.ejb.CreateException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.oreilly.jent.people.InvalidSearchException;
import com.oreilly.jent.people.PersistenceException;
import com.oreilly.jent.people.Person;
import com.oreilly.jent.people.PersonDAO;
import com.oreilly.jent.people.SearchArg;
import com.oreilly.jent.people.ejb.PeopleFinderLocal;
import com.oreilly.jent.people.ejb.PeopleFinderLocalHome;

public class PeopleFinderServlet extends HttpServlet {
    
    // Logger for this class
    private Logger mLog =
        Logger.getLogger(PeopleFinderServlet.class.getName());
    
    /**
     * Default constructor.
     */
    public PeopleFinderServlet() {
        super();
    }
    
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws IOException, ServletException {
        handleRequest(req, resp);
    }
    
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws IOException, ServletException {
        handleRequest(req, resp);
    }
    
    /** Main request handler, invoked from doGet() and doPost() methods */   
    private void handleRequest(HttpServletRequest request,
                               HttpServletResponse response) 
        throws ServletException, IOException {
        Person[] people = new Person[0];
        String error = null;
        
        // Convert the tag's attributes into a set of SearchArgs
        SearchArg[] sargs = new SearchArg[3];
        
        sargs[0] = new SearchArg();
        sargs[0].setName(PersonDAO.FIRST_NAME);
        sargs[0].setValue(request.getParameter("firstName"));
        
        sargs[1] = new SearchArg();
        sargs[1].setName(PersonDAO.LAST_NAME);
        sargs[1].setValue(request.getParameter("lastName"));
        
        sargs[2] = new SearchArg();
        sargs[2].setName(PersonDAO.EMAIL);
        sargs[2].setValue(request.getParameter("email"));
        
        // Get the PeopleFinder EJB home
        try {
            Context ctx = new InitialContext();
            PeopleFinderLocalHome home = 
                (PeopleFinderLocalHome)ctx.lookup("java:comp/env/ejb/junit-PeopleFinder");
            PeopleFinderLocal finder = home.create();
            people = finder.findPeople(sargs);
        }
        catch (NamingException ne) {
            error = "Failure accessing EJB component";
            mLog.severe("Failed to locate/access EJB component: " + ne.getMessage());
        }
        catch (CreateException ce) {
            error = "Failure accessing EJB component";
            mLog.severe("Failed to create EJB component: " + ce.getMessage());
        }
        catch (InvalidSearchException ise) {
            error = "Invalid search parameters.";
            mLog.severe("Search parameters were invalid: " + ise.getMessage());
        }
        catch (PersistenceException pe) {
            error = "Failure accessing data source";
            mLog.severe("Persistence error during search: " + pe.getMessage());
        }
        
        // Output HTML results
        PrintWriter out = response.getWriter();
        // Print the header
        out.println("<HTML><HEAD><TITLE>Search Results</TITLE></HEAD><BODY>");
        // If there's an error, just print it, prefaced with "Error:".
        if (error != null) {
            out.println("<center><h3>Error: " + error + "</h3></center>");
        }
        // If there are no results, print a notice to that effect
        else if (people.length == 0) {
            out.println("<center><h3>No matching people found.</h3></center>");
        }
        // Otherwise, print the results, one person per row, in a table
        else {
            // Open the table
            out.println("<center><table border=\"0\">");
            out.println("<tr bgcolor=\"#CCCCCC\">");
            out.println("<th>Last name</th>");
            out.println("<th>First name</th>");
            out.println("<th>Email addresses</th></tr>");
            // Print each person's data
            for (int i = 0; i < people.length; i++) {
                Person p = people[i];
                // Use our util method to convert the person
                // data into an HTML fragment
                out.println(personToHTML(p));
            }
            out.println("</table>");
        }
        // Close the page
        out.println("</BODY></HTML>");
    }
    
    /** 
     *  Convert a Person's data into a row in the table on the results page. 
     *  Note that this utility assumes a particular structure to the results
     *  page (a table with so many columns, with a particular order to the 
     *  data in the columns, etc.)
     */
    static protected String personToHTML(Person p) {
        StringBuffer buf = new StringBuffer();
        buf.append("<tr bgcolor=\"#EEEEEE\">");
        buf.append("<td>" + p.getLastName() + "</td>");
        buf.append("<td>" + p.getFirstName() + "</td>");
        buf.append("<td>");
        for (int i = 0; i < p.getEmailAddresses().length; i++) {
            buf.append(p.getEmailAddresses()[i]);
            if (i < p.getEmailAddresses().length - 1) {
                buf.append("<br>");
            }
        }
        buf.append("</td>");
        buf.append("</tr>");
        return buf.toString();
    }

}
