/**
   * Sell a current holding of stock shares for the given trader. Dispatch to the Trade Portfolio
   * JSP for display
   *
   * @param userID The User buying shares
   * @param symbol The stock to sell
   * @param indx The unique index identifying the users holding to sell
   * @param ctx the servlet context
   * @param req the HttpRequest object
   * @param resp the HttpResponse object
   * @exception javax.servlet.ServletException If a servlet specific exception is encountered
   * @exception javax.io.IOException If an exception occurs while writing results back to the user
   */
  void doSell(
      ServletContext ctx,
      HttpServletRequest req,
      HttpServletResponse resp,
      String userID,
      Integer holdingID)
      throws ServletException, IOException {
    String results = "";
    try {
      OrderDataBean orderData = tAction.sell(userID, holdingID, TradeConfig.orderProcessingMode);

      req.setAttribute("orderData", orderData);
      req.setAttribute("results", results);
    } catch (java.lang.IllegalArgumentException e) { // this is a user error so I will
      // just log the exception and then later on I will redisplay the portfolio page
      // because this is just a user exception
      Log.error(
          e,
          "TradeServletAction.doSell(...)",
          "illegal argument, information should be in exception string",
          "user error");
    } catch (Exception e) {
      // log the exception with error page
      throw new ServletException(
          "TradeServletAction.doSell(...)"
              + " exception selling holding "
              + holdingID
              + " for user ="
              + userID,
          e);
    }
    requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.ORDER_PAGE));
  }
  /**
   * Display User Profile information such as address, email, etc. for the given Trader Dispatch to
   * the Trade Account JSP for display
   *
   * @param userID The User to display profile info
   * @param ctx the servlet context
   * @param req the HttpRequest object
   * @param resp the HttpResponse object
   * @param results A short description of the results/success of this web request provided on the
   *     web page
   * @exception javax.servlet.ServletException If a servlet specific exception is encountered
   * @exception javax.io.IOException If an exception occurs while writing results back to the user
   */
  void doAccount(
      ServletContext ctx,
      HttpServletRequest req,
      HttpServletResponse resp,
      String userID,
      String results)
      throws javax.servlet.ServletException, java.io.IOException {
    try {

      AccountDataBean accountData = tAction.getAccountData(userID);
      AccountProfileDataBean accountProfileData = tAction.getAccountProfileData(userID);
      ArrayList orderDataBeans =
          (TradeConfig.getLongRun() ? new ArrayList() : (ArrayList) tAction.getOrders(userID));

      req.setAttribute("accountData", accountData);
      req.setAttribute("accountProfileData", accountProfileData);
      req.setAttribute("orderDataBeans", orderDataBeans);
      req.setAttribute("results", results);
      requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.ACCOUNT_PAGE));
    } catch (java.lang.IllegalArgumentException e) { // this is a user error so I will
      // forward them to another page rather than throw a 500
      req.setAttribute("results", results + "could not find account for userID = " + userID);
      requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.HOME_PAGE));
      // log the exception with an error level of 3 which means, handled exception but would
      // invalidate a automation run
      Log.error(
          "TradeServletAction.doAccount(...)",
          "illegal argument, information should be in exception string",
          e);
    } catch (Exception e) {
      // log the exception with error page
      throw new ServletException(
          "TradeServletAction.doAccount(...)" + " exception user =" + userID, e);
    }
  }
  /**
   * Logout a Trade User Dispatch to the Trade Welcome JSP for display
   *
   * @param userID The User to logout
   * @param ctx the servlet context
   * @param req the HttpRequest object
   * @param resp the HttpResponse object
   * @param results A short description of the results/success of this web request provided on the
   *     web page
   * @exception javax.servlet.ServletException If a servlet specific exception is encountered
   * @exception javax.io.IOException If an exception occurs while writing results back to the user
   */
  void doLogout(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String userID)
      throws ServletException, IOException {
    String results = "";

    try {
      tAction.logout(userID);

    } catch (java.lang.IllegalArgumentException e) { // this is a user error so I will
      // forward them to another page, at the end of the page.
      req.setAttribute("results", results + "illegal argument:" + e.getMessage());

      // log the exception with an error level of 3 which means, handled exception but would
      // invalidate a automation run
      Log.error(
          e,
          "TradeServletAction.doLogout(...)",
          "illegal argument, information should be in exception string",
          "treating this as a user error and forwarding on to a new page");
    } catch (Exception e) {
      // log the exception and foward to a error page
      Log.error(
          e,
          "TradeServletAction.doLogout(...):",
          "Error logging out" + userID,
          "fowarding to an error page");
      // set the status_code to 500
      throw new ServletException(
          "TradeServletAction.doLogout(...)" + "exception logging out user " + userID, e);
    }
    HttpSession session = req.getSession();
    if (session != null) {
      session.invalidate();
    }

    Object o = req.getAttribute("TSS-RecreateSessionInLogout");
    if (o != null && ((Boolean) o).equals(Boolean.TRUE)) {
      // Recreate Session object before writing output to the response
      // Once the response headers are written back to the client the opportunity
      // to create a new session in this request may be lost
      // This is to handle only the TradeScenarioServlet case
      session = req.getSession(true);
    }
    requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.WELCOME_PAGE));
  }
  /**
   * Update User Profile information such as address, email, etc. for the given Trader Dispatch to
   * the Trade Account JSP for display If any in put is incorrect revert back to the account page w/
   * an appropriate message
   *
   * @param userID The User to upddate profile info
   * @param password The new User password
   * @param cpassword Confirm password
   * @param fullname The new User fullname info
   * @param address The new User address info
   * @param cc The new User credit card info
   * @param email The new User email info
   * @param ctx the servlet context
   * @param req the HttpRequest object
   * @param resp the HttpResponse object
   * @exception javax.servlet.ServletException If a servlet specific exception is encountered
   * @exception javax.io.IOException If an exception occurs while writing results back to the user
   */
  void doAccountUpdate(
      ServletContext ctx,
      HttpServletRequest req,
      HttpServletResponse resp,
      String userID,
      String password,
      String cpassword,
      String fullName,
      String address,
      String creditcard,
      String email)
      throws javax.servlet.ServletException, java.io.IOException {
    String results = "";

    // First verify input data
    boolean doUpdate = true;
    if (password.equals(cpassword) == false) {
      results = "Update profile error: passwords do not match";
      doUpdate = false;
    } else if (password.length() <= 0
        || fullName.length() <= 0
        || address.length() <= 0
        || creditcard.length() <= 0
        || email.length() <= 0) {
      results = "Update profile error: please fill in all profile information fields";
      doUpdate = false;
    }
    AccountProfileDataBean accountProfileData =
        new AccountProfileDataBean(userID, password, fullName, address, email, creditcard);
    try {
      if (doUpdate) {
        accountProfileData = tAction.updateAccountProfile(accountProfileData);
        results = "Account profile update successful";
      }

    } catch (java.lang.IllegalArgumentException e) { // this is a user error so I will
      // forward them to another page rather than throw a 500
      req.setAttribute(
          "results",
          results
              + "invalid argument, check userID is correct, and the database is populated"
              + userID);
      Log.error(
          e,
          "TradeServletAction.doAccount(...)",
          "illegal argument, information should be in exception string",
          "treating this as a user error and forwarding on to a new page");
    } catch (Exception e) {
      // log the exception with error page
      throw new ServletException(
          "TradeServletAction.doAccountUpdate(...)" + " exception user =" + userID, e);
    }
    doAccount(ctx, req, resp, userID, results);
  }
  /**
   * Retrieve the current portfolio of stock holdings for the given trader Dispatch to the Trade
   * Portfolio JSP for display
   *
   * @param userID The User requesting to view their portfolio
   * @param ctx the servlet context
   * @param req the HttpRequest object
   * @param resp the HttpResponse object
   * @param results A short description of the results/success of this web request provided on the
   *     web page
   * @exception javax.servlet.ServletException If a servlet specific exception is encountered
   * @exception javax.io.IOException If an exception occurs while writing results back to the user
   */
  void doPortfolio(
      ServletContext ctx,
      HttpServletRequest req,
      HttpServletResponse resp,
      String userID,
      String results)
      throws ServletException, IOException {

    try {
      // Get the holdiings for this user

      Collection quoteDataBeans = new ArrayList();
      Collection holdingDataBeans = tAction.getHoldings(userID);

      // Walk through the collection of user
      //  holdings and creating a list of quotes
      if (holdingDataBeans.size() > 0) {

        Iterator it = holdingDataBeans.iterator();
        while (it.hasNext()) {
          HoldingDataBean holdingData = (HoldingDataBean) it.next();
          QuoteDataBean quoteData = tAction.getQuote(holdingData.getQuoteID());
          quoteDataBeans.add(quoteData);
        }
      } else {
        results = results + ".  Your portfolio is empty.";
      }
      req.setAttribute("results", results);
      req.setAttribute("holdingDataBeans", holdingDataBeans);
      req.setAttribute("quoteDataBeans", quoteDataBeans);
      requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.PORTFOLIO_PAGE));
    } catch (java.lang.IllegalArgumentException e) { // this is a user error so I will
      // forward them to another page rather than throw a 500
      req.setAttribute("results", results + "illegal argument:" + e.getMessage());
      requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.PORTFOLIO_PAGE));
      // log the exception with an error level of 3 which means, handled exception but would
      // invalidate a automation run
      Log.error(
          e,
          "TradeServletAction.doPortfolio(...)",
          "illegal argument, information should be in exception string",
          "user error");
    } catch (Exception e) {
      // log the exception with error page
      throw new ServletException(
          "TradeServletAction.doPortfolio(...)" + " exception user =" + userID, e);
    }
  }
 /** Return the hostname for this system Creation date: (2/16/2000 9:02:25 PM) */
 private static String getHostname() {
   try {
     if (hostName == null) {
       hostName = java.net.InetAddress.getLocalHost().getHostName();
       // Strip of fully qualifed domain if necessary
       try {
         hostName = hostName.substring(0, hostName.indexOf('.'));
       } catch (Exception e) {
       }
     }
   } catch (Exception e) {
     Log.error("Exception getting local host name using 'localhost' - ", e);
     hostName = "localhost";
   }
   return hostName;
 }
  /**
   * Buy a new holding of shares for the given trader Dispatch to the Trade Portfolio JSP for
   * display
   *
   * @param userID The User buying shares
   * @param symbol The stock to purchase
   * @param amount The quantity of shares to purchase
   * @param ctx the servlet context
   * @param req the HttpRequest object
   * @param resp the HttpResponse object
   * @exception javax.servlet.ServletException If a servlet specific exception is encountered
   * @exception javax.io.IOException If an exception occurs while writing results back to the user
   */
  void doBuy(
      ServletContext ctx,
      HttpServletRequest req,
      HttpServletResponse resp,
      String userID,
      String symbol,
      String quantity)
      throws ServletException, IOException {

    String results = "";

    try {
      OrderDataBean orderData =
          tAction.buy(
              userID, symbol, new Double(quantity).doubleValue(), TradeConfig.orderProcessingMode);

      req.setAttribute("orderData", orderData);
      req.setAttribute("results", results);
    } catch (java.lang.IllegalArgumentException e) { // this is a user error so I will
      // forward them to another page rather than throw a 500
      req.setAttribute("results", results + "illegal argument:");
      requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.HOME_PAGE));
      // log the exception with an error level of 3 which means, handled exception but would
      // invalidate a automation run
      Log.error(
          e,
          "TradeServletAction.doBuy(...)",
          "illegal argument. userID = " + userID,
          "symbol = " + symbol);
    } catch (Exception e) {
      // log the exception with error page
      throw new ServletException(
          "TradeServletAction.buy(...)"
              + " exception buying stock "
              + symbol
              + " for user "
              + userID,
          e);
    }
    requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.ORDER_PAGE));
  }
  /**
   * This is a convenience method for servlets to set Trade configuration parameters from servlet
   * initialization parameters. The servlet provides the init param and its value as strings. This
   * method then parses the parameter, converts the value to the correct type and sets the
   * corresponding TradeConfig parameter to the converted value
   */
  public static void setConfigParam(String parm, String value) {
    Log.log("TradeConfig setting parameter: " + parm + "=" + value);
    // Compare the parm value to valid TradeConfig parameters that can be set
    // by servlet initialization

    // First check the proposed new parm and value - if empty or null ignore it
    if (parm == null) return;
    parm = parm.trim();
    if (parm.length() <= 0) return;
    if (value == null) return;
    value = value.trim();

    if (parm.equalsIgnoreCase("runTimeMode")) {
      try {
        for (int i = 0; i < runTimeModeNames.length; i++) {
          if (value.equalsIgnoreCase(runTimeModeNames[i])) {
            runTimeMode = i;
            break;
          }
        }
      } catch (Exception e) {
        // >>rjm
        Log.error(
            "TradeConfig.setConfigParm(..): minor exception caught"
                + "trying to set runtimemode to "
                + value
                + "reverting to current value: "
                + runTimeModeNames[runTimeMode],
            e);
      } // If the value is bad, simply revert to current
    } else if (parm.equalsIgnoreCase("orderProcessingMode")) {
      try {
        for (int i = 0; i < orderProcessingModeNames.length; i++) {
          if (value.equalsIgnoreCase(orderProcessingModeNames[i])) {
            orderProcessingMode = i;
            break;
          }
        }
      } catch (Exception e) {
        Log.error(
            "TradeConfig.setConfigParm(..): minor exception caught"
                + "trying to set orderProcessingMode to "
                + value
                + "reverting to current value: "
                + orderProcessingModeNames[orderProcessingMode],
            e);
      } // If the value is bad, simply revert to current
    } else if (parm.equalsIgnoreCase("accessMode")) {
      try {
        for (int i = 0; i < accessModeNames.length; i++) {
          if (value.equalsIgnoreCase(accessModeNames[i])) {
            accessMode = i;
            break;
          }
        }
      } catch (Exception e) {
        Log.error(
            "TradeConfig.setConfigParm(..): minor exception caught"
                + "trying to set accessMode to "
                + value
                + "reverting to current value: "
                + accessModeNames[accessMode],
            e);
      }
    } else if (parm.equalsIgnoreCase("webServicesEndpoint")) {
      try {
        setSoapURL(value);
      } catch (Exception e) {
        Log.error(
            "TradeConfig.setConfigParm(..): minor exception caught"
                + "Setting web services endpoint",
            e);
      } // On error, revert to saved
    } else if (parm.equalsIgnoreCase("workloadMix")) {
      try {
        for (int i = 0; i < workloadMixNames.length; i++) {
          if (value.equalsIgnoreCase(workloadMixNames[i])) {
            workloadMix = i;
            break;
          }
        }
      } catch (Exception e) {
        Log.error(
            "TradeConfig.setConfigParm(..): minor exception caught"
                + "trying to set workloadMix to "
                + value
                + "reverting to current value: "
                + workloadMixNames[workloadMix],
            e);
      } // If the value is bad, simply revert to current
    } else if (parm.equalsIgnoreCase("WebInterface")) {
      try {
        for (int i = 0; i < webInterfaceNames.length; i++) {
          if (value.equalsIgnoreCase(webInterfaceNames[i])) {
            webInterface = i;
            break;
          }
        }
      } catch (Exception e) {
        Log.error(
            "TradeConfig.setConfigParm(..): minor exception caught"
                + "trying to set WebInterface to "
                + value
                + "reverting to current value: "
                + webInterfaceNames[webInterface],
            e);
      } // If the value is bad, simply revert to current
    } else if (parm.equalsIgnoreCase("CachingType")) {
      try {
        for (int i = 0; i < cachingTypeNames.length; i++) {
          if (value.equalsIgnoreCase(cachingTypeNames[i])) {
            cachingType = i;
            break;
          }
        }
      } catch (Exception e) {
        Log.error(
            "TradeConfig.setConfigParm(..): minor exception caught"
                + "trying to set CachingType to "
                + value
                + "reverting to current value: "
                + cachingTypeNames[cachingType],
            e);
      } // If the value is bad, simply revert to current
    } else if (parm.equalsIgnoreCase("maxUsers")) {
      try {
        MAX_USERS = Integer.parseInt(value);
      } catch (Exception e) {
        Log.error(
            "TradeConfig.setConfigParm(..): minor exception caught"
                + "Setting maxusers, error parsing string to int:"
                + value
                + "revering to current value: "
                + MAX_USERS,
            e);
      } // On error, revert to saved
    } else if (parm.equalsIgnoreCase("maxQuotes")) {
      try {
        MAX_QUOTES = Integer.parseInt(value);
      } catch (Exception e) {
        // >>rjm
        Log.error(
            "TradeConfig.setConfigParm(...) minor exception caught"
                + "Setting max_quotes, error parsing string to int "
                + value
                + "reverting to current value: "
                + MAX_QUOTES,
            e);
        // <<rjm
      } // On error, revert to saved
    } else if (parm.equalsIgnoreCase("primIterations")) {
      try {
        primIterations = Integer.parseInt(value);
      } catch (Exception e) {
        Log.error(
            "TradeConfig.setConfigParm(..): minor exception caught"
                + "Setting primIterations, error parsing string to int:"
                + value
                + "revering to current value: "
                + primIterations,
            e);
      } // On error, revert to saved
    } else if (parm.equalsIgnoreCase("LongRun")) {
      try {
        longRun = value.equalsIgnoreCase("true");
      } catch (Exception e) {
        Log.error(
            "TradeConfig.setConfigParm(..): minor exception caught"
                + "Setting primIterations, error parsing string to int:"
                + value
                + "revering to current value: "
                + longRun,
            e);
      } // On error, revert to saved
    }
  }
  public static String rndUserID() {
    String nextUser = getNextUserIDFromDeck();
    if (Log.doTrace()) Log.trace("TradeConfig:rndUserID -- new trader = " + nextUser);

    return nextUser;
  }
 public void print() {
   Log.log(this.toString());
 }
  /**
   * Login a Trade User. Dispatch to the Trade Home JSP for display
   *
   * @param userID The User to login
   * @param passwd The password supplied by the trader used to authenticate
   * @param ctx the servlet context
   * @param req the HttpRequest object
   * @param resp the HttpResponse object
   * @param results A short description of the results/success of this web request provided on the
   *     web page
   * @exception javax.servlet.ServletException If a servlet specific exception is encountered
   * @exception javax.io.IOException If an exception occurs while writing results back to the user
   */
  void doLogin(
      ServletContext ctx,
      HttpServletRequest req,
      HttpServletResponse resp,
      String userID,
      String passwd)
      throws javax.servlet.ServletException, java.io.IOException {
    System.out.println("Login userID: " + userID);
    String results = "";
    try {
      // Got a valid userID and passwd, attempt login

      AccountDataBean accountData = tAction.login(userID, passwd);

      if (accountData != null) {
        HttpSession session = req.getSession(true);
        session.setAttribute("uidBean", userID);
        session.setAttribute("sessionCreationDate", new java.util.Date());
        if (("true").equals(req.getParameter("stress"))) {
          // fib(35);
          char[] s = new char[10 * 1024 * 1000];
          String str = String.copyValueOf(s);
          session.setAttribute("someobject", str);
        }
        results = "Ready to Trade";
        doHome(ctx, req, resp, userID, results);
        return;
      } else {
        req.setAttribute("results", results + "\nCould not find account for + " + userID);
        // log the exception with an error level of 3 which means, handled exception but would
        // invalidate a automation run
        Log.log(
            "TradeServletAction.doLogin(...)",
            "Error finding account for user " + userID + "",
            "user entered a bad username or the database is not populated");
      }
    } catch (java.lang.IllegalArgumentException e) { // this is a user error so I will
      // forward them to another page rather than throw a 500
      req.setAttribute("results", results + "illegal argument:" + e.getMessage());
      // log the exception with an error level of 3 which means, handled exception but would
      // invalidate a automation run
      Log.error(
          e,
          "TradeServletAction.doLogin(...)",
          "illegal argument, information should be in exception string",
          "treating this as a user error and forwarding on to a new page");

    } catch (Exception e) {
      doWelcome(
          ctx,
          req,
          resp,
          "User not found! Is the database <a href = 'config?action=buildDB'>populated </a>?");
      return;
      /*			throw new ServletException(
      "TradeServletAction.doLogin(...)"
      	+ "Exception logging in user "
      	+ userID
      	+ "with password"
      	+ passwd
      	,e);
      	*/

    }

    requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.WELCOME_PAGE));
  }
  /**
   * Create the Trade Home page with personalized information such as the traders account balance
   * Dispatch to the Trade Home JSP for display
   *
   * @param ctx the servlet context
   * @param req the HttpRequest object
   * @param resp the HttpResponse object
   * @param results A short description of the results/success of this web request provided on the
   *     web page
   * @exception javax.servlet.ServletException If a servlet specific exception is encountered
   * @exception javax.io.IOException If an exception occurs while writing results back to the user
   */
  void doHome(
      ServletContext ctx,
      HttpServletRequest req,
      HttpServletResponse resp,
      String userID,
      String results)
      throws javax.servlet.ServletException, java.io.IOException {
    BigDecimal balance;
    String result = "";
    try {
      AccountDataBean accountData = tAction.getAccountData(userID);
      Collection holdingDataBeans = tAction.getHoldings(userID);

      // Edge Caching:
      // Getting the MarketSummary has been moved to the JSP
      // MarketSummary.jsp. This makes the MarketSummary a
      // standalone "fragment", and thus is a candidate for
      // Edge caching.
      // marketSummaryData = tAction.getMarketSummary();

      req.setAttribute("accountData", accountData);
      req.setAttribute("holdingDataBeans", holdingDataBeans);
      // See Edge Caching above
      // req.setAttribute("marketSummaryData", marketSummaryData);
      req.setAttribute("results", results);
    } catch (java.lang.IllegalArgumentException e) { // this is a user error so I will
      // forward them to another page rather than throw a 500
      req.setAttribute(
          "results", results + "check userID = " + userID + " and that the database is populated");
      requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.HOME_PAGE));
      // log the exception with an error level of 3 which means, handled exception but would
      // invalidate a automation run
      Log.error(
          "TradeServletAction.doHome(...)"
              + "illegal argument, information should be in exception string"
              + "treating this as a user error and forwarding on to a new page",
          e);
    }
    // ALPINE No support for EJB's yet
    /*catch (javax.ejb.FinderException e)
    {
    	//this is a user error so I will
    	//forward them to another page rather than throw a 500
    	req.setAttribute(
    		"results",
    		results + "\nCould not find account for + " + userID);
    	//requestDispatch(ctx, req, resp, TradeConfig.getPage(TradeConfig.HOME_PAGE));
    	//log the exception with an error level of 3 which means, handled exception but would invalidate a automation run
    	Log.error(
    		"TradeServletAction.doHome(...)" +
    		"Error finding account for user " + userID +
    		"treating this as a user error and forwarding on to a new page", e);
    }*/
    catch (Exception e) {
      // log the exception with error page
      throw new ServletException(
          "TradeServletAction.doHome(...)" + " exception user =" + userID, e);
    }

    requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.HOME_PAGE));
  }