/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999-2004 Bull S.A.
 * Contact: jonas-team@objectweb.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * Initial developer(s):
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Calendar;
import java.util.Vector;

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

import com.titan.address.AddressHomeLocal;
import com.titan.address.AddressLocal;
import com.titan.customer.CreditCardHomeLocal;
import com.titan.customer.CreditCardLocal;
import com.titan.customer.CustomerHomeLocal;
import com.titan.customer.CustomerLocal;
import com.titan.customer.Name;
import com.titan.phone.PhoneLocal;



/**
 * This servlet is used  to test O'Reilly examples
 * @author JOnAS team
 */
public class ServletTest extends HttpServlet {

    /**
     * Called by the server (via the service method) to allow a servlet to
     * handle a GET request.
     * @param request an HttpServletRequest object that contains the request
     * the client has made of the servlet
     * @param response an HttpServletResponse object that contains the
     * response the servlet sends to the client
     * @throws IOException if an input or output error is detected when the
     * servlet handles the GET request
     * @throws ServletException if the request for the GET could not be handled
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {

        boolean ok = true;
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        out.println("<html>");
        out.println("<head>");
        out.println("<title>");
        out.println("O'Reilly Examples</title>");
        out.println("<link rel=\"stylesheet\" href=\"style.css\" />");
        out.println("</head>");
        out.println("<body style=\"background : white; color : black;\">");
        out.println("<h1>Examples 1:1 Relationships</h1>");

        Context initialContext = null;
        try {
            initialContext = new InitialContext();
        } catch (Exception e) {
            out.println("<p>ERROR: Cannot get initial context for JNDI: " + e + "</p>");
            return;
        }

        out.println("<a href=\"index.html\"><b>Back to Menu</b></a>");


        out.println("<h2>Example showing CreditCard/Customer relationship</h2>");

        out.println("<p>(ie Setting reference in a one-to-one bidirectional relationship)</p>");

        // Connecting to CustomerHomeLocal and CreditCardHomeLocal thru JNDI
        CustomerHomeLocal customerhome = null;
        CreditCardHomeLocal cardhome = null;
        AddressHomeLocal addresshome = null;

        try {
            customerhome  = (CustomerHomeLocal)
                initialContext.lookup("java:comp/env/ejb/CustomerHomeLocal");
            cardhome = (CreditCardHomeLocal)
                initialContext.lookup("java:comp/env/ejb/CreditCardHomeLocal");
            addresshome = (AddressHomeLocal)
                initialContext.lookup("java:comp/env/ejb/AddressHomeLocal");
        } catch (Exception e) {
            out.println("<p>ERROR: Cannot lookup java:comp/env/ejb/XXHomeLocal: "
                        + e + "</p>");
            return;
        }

        out.println("<h3>Creating Customer 'Smith'.</h3>");
        Integer primaryKey = new Integer(71);
        CustomerLocal customer = null;
        try {
            customer = customerhome.create(primaryKey);
        } catch (javax.ejb.CreateException ex) {
            out.println("<p>Cannot create customer: "
                        + ex + "</p>");
            return;
        }
        customer.setName(new Name("Smith", "John"));

        out.println("<h3>Creating CreditCard.</h3>");
        // set Credit Card info
        Calendar now = Calendar.getInstance();
        CreditCardLocal card = null;
        try {
            card = cardhome.create(now.getTime(), "370000000000001", "John Smith", "O'Reilly");
        } catch (javax.ejb.CreateException ex) {
            out.println("<p>ERROR: Cannot create creditcard : " + ex + " </p>");
            return;
        }

        out.println("<H3>Linking CreditCard and Customer.</H3>");
        customer.setCreditCard(card);

        out.println("<H3>Testing both directions on relationship:</H3>");
        String cardname = customer.getCreditCard().getNameOnCard();
        out.println("customer.getCreditCard().getNameOnCard() = '" + cardname + "'<br>");
        Name name = card.getCustomer().getName();
        String custfullname = name.getFirstName() + " " + name.getLastName();
        out.println("card.getCustomer().getName() = '" + custfullname + "'<br>");
        if (!cardname.equals(custfullname)) {
            out.println("<p>ERROR: The name must be the same</p>");
            ok = false;
        }
        out.println("<H3>Content of Tables:</H3>");
        try {
            listCustomers(out, customerhome);
            listCreditcards(out, cardhome);
        } catch (Exception e) {
            out.println("<p>ERROR: exception caught = " + e + "</p>");
        }

        out.println("<H3>Unlink the beans using CreditCard, test Customer side:</H3>");
        card.setCustomer(null);
        CreditCardLocal newcardref = customer.getCreditCard();
        if (newcardref == null) {
            out.print("<p>Card is properly unlinked from customer bean</p>");
        } else {
            out.print("<p>ERROR: Whoops, customer still thinks it has a card !</p>");
            ok = false;
        }
        // relink to avoid side effect on further test
        card.setCustomer(customer);


        out.println("<h2>Example Showing Customer/Address Relationship</h2>");
        out.println("<p>(ie Setting reference in a one-to-one unidirectional relationship)</p>");

        // Find Customer 71
        primaryKey = new Integer(71);
        try {
            customer = customerhome.findByPrimaryKey(primaryKey);
        } catch (Exception e) {
            out.println("<p>ERROR: Exception : " + e + "</p>");
            return;
        }

        AddressLocal addr = customer.getHomeAddress();
        if (addr == null) {
            out.println("<h3>Address reference is NULL, Creating one and setting in Customer:</h3>");
            try {
                addr = addresshome.createAddress("333 North Washington", "Minneapolis", "MN", "55401");
            } catch (Exception e) {
                out.println("<p>ERROR: Exception : " + e + "</p>");
                return;
            }
            customer.setHomeAddress(addr);
        }
        out.println("<p>Address Info: "
                    + addr.getStreet() + ", "
                    + addr.getCity() + ", "
                    + addr.getState() + ", "
                    + addr.getZip() + "</p>");
        // Modifying Address

        out.println("<H3>Modifying Address through address reference:</H3>");
        addr.setStreet("445 East Lake Street");
        addr.setCity("Wayzata");
        addr.setState("MN");
        addr.setZip("55432");
        out.println("<p>Address Info: "
                    + addr.getStreet() + ", "
                    + addr.getCity() + ", "
                    + addr.getState() + ", "
                    + addr.getZip() + "</p>");

        out.print("<H3>Creating New Address and calling setHomeAddress():</H3>");
        AddressLocal addrold = addr;
        try {
            addr = addresshome.createAddress("700 Main Street", "St. Paul", "MN", "55302");
        } catch (Exception e) {
            out.println("<p>ERROR: Exception : " + e + "</p>");
            return;
        }
        out.println("<p>Address Info: "
                    + addr.getStreet() + ", "
                    + addr.getCity() + ", "
                    + addr.getState() + ", "
                    + addr.getZip() + "</p>");
        customer.setHomeAddress(addr);

        // Note: Original Address remains in database, orphaned by setHomeAddress call..


        out.print("<H3>Retrieving Address reference from Customer via getHomeAddress():</H3>");
        addr = customer.getHomeAddress();
        out.print("<p>Address Info: "
                  + addr.getStreet() + ", "
                  + addr.getCity() + ", "
                  + addr.getState() + ", "
                  + addr.getZip() + "</p>");

        out.print("<H3>Content of Tables:</H3>");
        try {
            listCustomers(out, customerhome);
            listAddress(out, addresshome);
        } catch (Exception e) {
            out.println("<p>ERROR: exception caught = " + e + "</p>");
            return;
        }


        out.println("<h2>Example Showing Customer/Phone Relationship</h2>");

        // Display current phone numbers and types
        out.println("<h3>Starting content of phone list:</h3>");

        Vector vv = customer.getPhoneList();
        listPhones(out, vv);

        // add a new phone number
        out.println("<h3>Adding a new type '1' phone number to Customer 'John Smith'.</h3>");
        try {
            customer.addPhoneNumber("612-555-1212", (byte) 1);
        } catch (Exception e) {
            out.println("<p>ERROR: Exception : " + e + "</p>");
            return;
        }

        out.println("<h3>New content of phone list for customer 'John Smith':</h3>");
        vv = customer.getPhoneList();
        listPhones(out, vv);

        // add a new phone number
        out.println("<h3>Adding a new type '2' phone number to Customer 'John Smith'.</h3>");
        try {
            customer.addPhoneNumber("800-333-3333", (byte) 2);
        } catch (Exception e) {
            out.println("<p>ERROR: Exception : " + e + "</p>");
            return;
        }
        out.println("<h3>New content of phone list for customer 'John Smith':</h3>");
        vv = customer.getPhoneList();
        listPhones(out, vv);

        // update a phone number
        out.println("<h3>Updating type '1' phone numbers.</h3>");
        try {
            customer.updatePhoneNumber("763-555-1212", (byte) 1);
        } catch (Exception e) {
            out.println("<p>ERROR: Exception : " + e + "</p>");
            return;
        }

        out.println("<h3>New content of phone list for customer 'John Smith':</h3>");
        vv = customer.getPhoneList();
        listPhones(out, vv);

        // delete a phone number
        out.print("<h3>Removing type '1' phone numbers from this Customer.</h3>");
        customer.removePhoneNumber((byte) 1);

        out.println("<h3>Final content of phone list:</h3>");
        vv = customer.getPhoneList();
        listPhones(out, vv);
        // Note that the phone is still in the database,
        // but it is no longer related to this customer bean

        // Remove newly created beans for clean
        out.println("<H2>Remove newly created beans for cleaning.</H2>");
        try {
            customer.remove();
            addrold.remove();
        } catch (Exception e) {
            out.println("<p>Exception : " + e + "</p>");
            return;
        }

        if (ok) {
            out.println("<p align=\"center\"><strong>Servlet is OK.</strong></p>");
        }

        out.println("<a href=\"index.html\"><b>Back to Menu</b></a>");
        out.println("</body>");
        out.println("</html>");
    }

    private void listCustomers (PrintWriter out, CustomerHomeLocal chl) throws Exception  {
        out.println("<p><b>Customers</b> Table Content:</p>");
        out.println("<ul>");
        java.util.Collection clc = chl.findAllCustomers();
        if (clc == null) {
            out.println("<li>Customers table is empty</li>");
        } else {
            java.util.Iterator iterator = clc.iterator();
            while (iterator.hasNext()) {
                CustomerLocal cl = (CustomerLocal) iterator.next();
                String  name = cl.getName().getLastName();
                String number = cl.getCreditCard().getNumber();
                out.print("<li>customerLastName = '" + name + "', creditCardNumber = '" + number);
                if (cl.getHomeAddress() != null) {
                    String city = cl.getHomeAddress().getCity();
                    out.print("', city = '" + city);
                }
                out.println("'</li>");
                java.util.Collection phoneNumbers = cl.getPhoneNumbers();
                java.util.Iterator phiterator = phoneNumbers.iterator();
                out.println("<ul>");
                while (phiterator.hasNext()) {
                    PhoneLocal phone = (PhoneLocal) phiterator.next();
                    out.println("<li>phoneType = '" + phone.getType()
                                + "', phoneNumber = '" + phone.getNumber() + "'</li>");
                }
                out.println("</ul>");

            }
        }
        out.println("</ul>");
    }

    private void listCreditcards (PrintWriter out, CreditCardHomeLocal cchl) throws Exception {
        out.println("<p><b>Creditcards</b> Table Content:</p>");
        out.println("<ul>");
        java.util.Collection clc = cchl.findAllCreditCards();
        if (clc == null) {
            out.println("<li>CreditCards table is empty</li>");
        } else {
            java.util.Iterator iterator = clc.iterator();
            while (iterator.hasNext()) {
                CreditCardLocal ccl = (CreditCardLocal) iterator.next();
                String number = ccl.getNumber();
                String  name = ccl.getNameOnCard();
                out.println("<li>creditCardNumber = '" + number
                            + "', nameOnCard = '" + name + "'</li>");
            }
        }
        out.println("</ul>");
    }

    private void listAddress (PrintWriter out, AddressHomeLocal cchl) throws Exception  {
        out.println("<p><b>Addresses</b> Table Content:</p>");
        out.println("<ul>");
        java.util.Collection clc = cchl.findAllAddress();
        if (clc == null) {
            out.println("<li>Addresses table is empty</li>");
        } else {
            java.util.Iterator iterator = clc.iterator();
            while (iterator.hasNext()) {
                AddressLocal al = (AddressLocal) iterator.next();
                String city = al.getCity();
                String street = al.getStreet();
                out.println("<li>city = '" + city + "', street = '" + street + "'</li>");
            }
        }
        out.println("</ul>");
    }

    private void listPhones(PrintWriter out, Vector vv) {
        out.println("<ul>");
        if (vv.size() == 0) {
                out.println("<li>phones list is empty</li>");
        } else {
            for (int jj = 0; jj < vv.size(); jj++) {
                String ss = (String) (vv.get(jj));
                out.println("<li>" + ss + "</li>");
            }
        }
        out.println("</ul>");
    }

}
