package examples.ejb.basic.beanManaged;

import java.io.IOException;
import java.io.OutputStream;
import java.rmi.RemoteException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;

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

import weblogic.html.BreakElement;
import weblogic.html.HeadingElement;
import weblogic.html.ServletPage;
import weblogic.html.StringElement;

/**
 * This servlet is a program similar to that in the
 * <a href="examples.ejb.basic.beanManaged.Client.html">examples.ejb.basic.beanManaged.Client</a>
 * example.
 * <p>
 * The servlet must be registered in the <code>weblogic.properties</code> file
 * of the WebLogic Server:
 * <p>
 * <code>weblogic.httpd.register.beanManaged=examples.ejb.basic.beanManaged.Servlet</code>
 * <code>weblogic.allow.execute.weblogic.servlet.beanManaged=<i>servletUser</i></code>
 * <code>weblogic.password.<i>servletUser</i>=<i>servletUserPassword</i></code>
 * <p>
 * Call this servlet using an URL such as 
 * <p>
 * <code>http://localhost:7001/beanManaged?user=servletUser&password=servletUserPassword</code>
 * <p>
 * where you've substituted appropriate values for <i>servletUser</i> and <i>servletUserPassword</i>
 * in both the <code>weblogic.properties</code> file and the URL.
 *
 * @author Adapted by WebLogic, Inc.; adaptions copyright (c) 1998 by WebLogic, Inc. All Rights Reserved. 
 * @author <br>Adapted by BEA Systems, Inc.; adaptions copyright (c) 1998-2000 by BEA Systems, Inc. All Rights Reserved. 
 */
public class Servlet extends HttpServlet { 

  static String accountId    = "10020";

  /**
   * Builds an HTML page, finds the beanManaged home,
   * creates beans and calls methods on the bean's remote interfaces.
   * 
   * @param req               HttpServletRequest
   * @param res               HttpServletResponse
   * @exception               java.io.IOException
   *                          if there is an IO error
   */
  public void service(HttpServletRequest req, HttpServletResponse res)
    throws IOException 
  {
    res.setContentType("text/html");
    OutputStream out = res.getOutputStream();
    String title = "EJBean Bean-managed Persistence Servlet";
 
    ServletPage sp = new ServletPage(title);
    sp.getBody()
      .addElement(new HeadingElement(title, 1));
    printElement("", sp);

    // Get parameters off URL; example: 
    // "http://localhost:7001/beanManaged?user=foobar&password=FooBarNone"

    String user     = req.getParameter("user");
    String password = req.getParameter("password");

    if(user!=null && password!=null){
      printElement("Using user <b>" + user
                   + "</b> and password <b> " + password + "</b>", sp);
      printElement("", sp);
    } else {
      printElement("No user and password credentials", sp);
      printElement("", sp);
    }
    
    double amount  = 100;
    double balance = 3000;
    Vector v = new Vector();

    try {
      // Contact the AccountBean container (the "AccountHome") through JNDI.
      Context ctx = getInitialContext();
      AccountHome home = (AccountHome) ctx.lookup("beanManaged.AccountHome");

      // Find the Account or create it.
      Account ac = null;
      try {
        printElement("Looking up account " + accountId + "...", sp);
        ac = (Account) home.findByPrimaryKey(accountId);
      } 
      catch (Exception ee) {
        printElement("Did not find " + accountId, sp);
      }

      if (ac == null) {
        printElement("Account " + accountId + 
                           " being created; opening balance is $" + balance, sp);
        ac = home.create(accountId, balance);      
      } 
      else {
        printElement("Account " + accountId + " found; balance is $" + ac.balance(), sp);
      }
      printElement("", sp);

      // Part A: Deposit and attempt to withdraw more than the current
      // account balance. An application-specific exception should be thrown.

      printElement("Part A: Depositing $" + amount, sp);
      balance = ac.deposit(amount);
      printElement("Current balance is $" + balance, sp);
      printElement("", sp);

      amount = balance + 10;
      try {
        printElement("Withdrawing amount greater than current balance. Expecting an exception...", sp);
        balance = ac.withdraw(amount);
        printElement("Error: expected an exception.", sp);
      } 
      catch (ProcessingErrorException pe) {
        printElement("Received expected Processing Error:<br>" + pe, sp);
      }
      printElement("", sp);

      // Part B: Create some new accounts, with different initial balances.
      // Find all the accounts with a balance greater than a specific value.
      // When finished, the new accounts are removed.

      int numAccounts = 5;
      printElement("Part B: Creating " + numAccounts + " new accounts...", sp);
      long now = System.currentTimeMillis();
      for (int i = 0; i < numAccounts; i++) {
        String id = "" + now + i;  // unique account  id
        balance = i*100; // initial balance
        v.addElement(home.create(id, balance)); 
        printElement("Created account: " + id + 
                           "; balance is $" + balance, sp);
      }
      printElement("", sp);

      if (v.size() == numAccounts) {
        printElement("" + numAccounts + " accounts successfully created", sp);
      }
      else {
        printElement("Error: Only " + v.size() + 
                           " accounts were created successfully", sp);
      }
      printElement("", sp);

      double balanceGreaterThan = 200;
      printElement("Querying for accounts with a balance greater than " +
                         balanceGreaterThan + "...", sp);
      Enumeration e = home.findBigAccounts(balanceGreaterThan);
      if (e != null) {
        while (e.hasMoreElements()) {
          Account bigAccount= (Account) e.nextElement();
          printElement("Account " + bigAccount.getPrimaryKey() + 
                             "; balance is $" + bigAccount.balance(), sp);
          Thread.sleep(1000);
        }
      }
      printElement("", sp);

      printElement("Removing accounts just created...", sp);
      for (int i = 0; i < numAccounts; i++) {
        String id = "" + now + i; 
        ((Account)(v.elementAt(i))).remove();
        printElement("Removed account: " +id, sp);
      }
      printElement("", sp);

    // Catch any exceptions
    } 
    catch (ProcessingErrorException pe) {
      printElement("Unexpected Processing Error: " + pe, sp);
    }
    catch (Exception e) {
      printElement(":::::::::::::: Unexpected Error :::::::::::::::::", sp);
      e.printStackTrace();
    }
    finally {
      printElement("End beanManaged.Servlet...", sp);
    }

    sp.output(out);
    out.flush();
  }
  
  /**
   * Basic servlet information.
   */
  public String getServletInfo() {
    return "EJBean Servlet";
  }

  /**
   * Prints to the HTML stream information on a bean.
   */
  static private void printAccount(Account account, ServletPage sp)
    throws RemoteException, IOException {
    printElement("Account " + account.getPrimaryKey() + 
                 "; balance is $" + account.balance(), sp);
  }

  /**
   * Prints message to browser.
   */
  static private void printElement(String message, ServletPage sp) 
    throws IOException {
    sp.getBody()
      .addElement(new BreakElement())
      .addElement(new StringElement(message));
  }

  /**
   * Gets an initial context for the current user, password and url.
   *
   * @return                  Context
   * @exception               java.lang.Exception if there is
   *                          an error in getting the Context
   */
  static public Context getInitialContext() throws Exception {
    Properties p = new Properties();
    p.put(Context.INITIAL_CONTEXT_FACTORY,
        "weblogic.jndi.WLInitialContextFactory");
    return new InitialContext(p);
  }
}
