blob: d0593660e19491f3d190432ec96276e46ed64b28 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.openjpa.integration.daytrader;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import javax.persistence.EntityManagerFactory;
import org.apache.openjpa.lib.log.Log;
/**
* OpenJPA created TradeAction, which was adapted from TradeServletAction.
* TradeServletAction provides servlet specific client side access to each of
* the Trade brokerage user operations. These include login, logout, buy, sell,
* getQuote, etc. TradeServletAction manages a web interface to Trade handling
* HttpRequests/HttpResponse objects and forwarding results to the appropriate
* JSP page for the web interface. TradeServletAction invokes
* {@link TradeAction} methods to actually perform each trading operation.
*
*/
public class TradeAction extends TradeJPADirect {
public TradeAction(Log log, EntityManagerFactory emf, boolean poolEm) {
super(log, emf, poolEm);
}
/**
* Display User Profile information such as address, email, etc. for the
* given Trader Dispatch to the Trade Account JSP for display
*
*/
void doAccount(StringBuilder sb, String userID, String results)
throws RuntimeException, java.io.IOException {
setAttribute(sb, "Page", "Account");
try {
AccountDataBean accountData = getAccountData(userID);
AccountProfileDataBean accountProfileData = getAccountProfileData(userID);
ArrayList orderDataBeans = (TradeConfig.getLongRun() ?
new ArrayList() : (ArrayList)getOrders(userID));
setAttribute(sb, "accountData", accountData);
setAttribute(sb, "accountProfileData", accountProfileData);
setAttribute(sb, "orderDataBeans", orderDataBeans);
setAttribute(sb, "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
setAttribute(sb, "results", results + "could not find account for userID = " + userID);
// redirect to home page
// log the exception with an error level of 3 which means, handled
// exception but would invalidate a automation run
setAttribute(sb, "Exception", e);
} catch (Exception e) {
// log the exception with error page
sb.append("TradeServletAction.doAccount(...)" + " exception user =" + userID);
setAttribute(sb, "Exception", e);
throw new RuntimeException("TradeServletAction.doAccount(...)" + " exception user =" + userID, e);
}
}
/**
* 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
*
*/
void doAccountUpdate(StringBuilder sb, String userID, String password,
String cpassword, String fullName, String address,
String creditcard, String email)
throws RuntimeException, java.io.IOException {
String results = "";
setAttribute(sb, "Page", "Account Update");
// First verify input data
boolean doUpdate = true;
if (!password.equals(cpassword)) {
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 = 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
setAttribute(sb, "results",
results + "invalid argument, check userID is correct, and the database is populated" + userID);
setAttribute(sb, "Exception", e);
} catch (Exception e) {
// log the exception with error page
setAttribute(sb, "results", "TradeServletAction.doAccountUpdate(...)" + " exception user =" + userID);
setAttribute(sb, "Exception", e);
throw new RuntimeException("TradeServletAction.doAccountUpdate(...)" + " exception user =" + userID, e);
} finally {
sb.append(results);
}
doAccount(sb, userID, results);
}
/**
* Buy a new holding of shares for the given trader Dispatch to the Trade
* Portfolio JSP for display
*
*/
void doBuy(StringBuilder sb, String userID, String symbol,
String quantity) throws RuntimeException, IOException {
String results = "";
setAttribute(sb, "Page", "Buy");
try {
OrderDataBean orderData = buy(userID, symbol, new Double(
quantity), TradeConfig.orderProcessingMode);
setAttribute(sb, "orderData", orderData);
setAttribute(sb, "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
setAttribute(sb, "results", results + "illegal argument. userID=" + userID + ", symbol=" + symbol);
setAttribute(sb, "Exception", e);
// 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
} catch (Exception e) {
// log the exception with error page
setAttribute(sb, "Exception", e);
throw new RuntimeException("TradeServletAction.buy(...)"
+ " exception buying stock " + symbol + " for user "
+ userID, e);
}
// requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.ORDER_PAGE));
}
/**
* Create the Trade Home page with personalized information such as the
* traders account balance Dispatch to the Trade Home JSP for display
*
*/
void doHome(StringBuilder sb, String userID, String results)
throws RuntimeException, java.io.IOException {
BigDecimal balance;
String result = "";
setAttribute(sb, "Page", "Home");
try {
AccountDataBean accountData = getAccountData(userID);
Collection holdingDataBeans = 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.
MarketSummaryDataBean marketSummaryData = getMarketSummary();
setAttribute(sb, "accountData", accountData);
setAttribute(sb, "holdingDataBeans", holdingDataBeans);
// See Edge Caching above
setAttribute(sb, "marketSummaryData", marketSummaryData);
setAttribute(sb, "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
setAttribute(sb, "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
setAttribute(sb, "Exception", e);
} catch (RuntimeException e) {
// this is a user error so I will
// forward them to another page rather than throw a 500
setAttribute(sb, "results", results + " Could 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
setAttribute(sb, "Exception", e);
} catch (Exception e) {
// log the exception with error page
setAttribute(sb, "Exception", e);
throw new RuntimeException("TradeServletAction.doHome(...)" + " exception user =" + userID, e);
}
// requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.HOME_PAGE));
}
/**
* Login a Trade User. Dispatch to the Trade Home JSP for display
*
*/
boolean doLogin(StringBuilder sb, String userID, String passwd)
throws RuntimeException, java.io.IOException {
String results = "";
setAttribute(sb, "Page", "Login");
try {
// Got a valid userID and passwd, attempt login
AccountDataBean accountData = login(userID, passwd);
if (accountData != null) {
// HttpSession session = req.getSession(true);
setAttribute(sb, "uidBean", userID);
setAttribute(sb, "sessionCreationDate", new java.util.Date());
results = "Ready to Trade";
doHome(sb, userID, results);
return true;
} else {
setAttribute(sb, "results", results + " Could not find account for + " + userID);
// log the exception with an error level of 3 which means,
// handled exception but would invalidate a automation run
}
} catch (java.lang.IllegalArgumentException e) {
// this is a user error so I will
// forward them to another page rather than throw a 500
setAttribute(sb, "results", results + "illegal argument. userID=" + userID + ", passwd=" + passwd);
// log the exception with an error level of 3 which means, handled
// exception but would invalidate a automation run
setAttribute(sb, "Exception", e);
} catch (Exception e) {
// log the exception with error page
setAttribute(sb, "Exception", e);
throw new RuntimeException("TradeServletAction.doLogin(...)"
+ "Exception logging in user " + userID + "with password"
+ passwd, e);
}
// requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.WELCOME_PAGE));
return false;
}
/**
* Logout a Trade User Dispatch to the Trade Welcome JSP for display
*
*/
void doLogout(StringBuilder sb, String userID) throws RuntimeException,
IOException {
String results = "";
setAttribute(sb, "Page", "Logout");
try {
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.
setAttribute(sb, "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
setAttribute(sb, "Exception", e);
} catch (Exception e) {
// log the exception and foward to a error page
setAttribute(sb, "Exception", e);
throw new RuntimeException("TradeServletAction.doLogout(...)"
+ "exception logging out user " + userID, e);
}
// requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.WELCOME_PAGE));
}
/**
* Retrieve the current portfolio of stock holdings for the given trader
* Dispatch to the Trade Portfolio JSP for display
*
*/
void doPortfolio(StringBuilder sb, String userID, String results)
throws RuntimeException, IOException {
setAttribute(sb, "Page", "Portfolio");
try {
// Get the holdiings for this user
Collection quoteDataBeans = new ArrayList();
Collection holdingDataBeans = 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 = getQuote(holdingData.getQuoteID());
quoteDataBeans.add(quoteData);
}
} else {
results = results + ". Your portfolio is empty.";
}
setAttribute(sb, "results", results);
setAttribute(sb, "holdingDataBeans", holdingDataBeans);
setAttribute(sb, "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
setAttribute(sb, "results", results + "illegal argument for userID=" + userID);
setAttribute(sb, "Exception", e);
// 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
} catch (Exception e) {
// log the exception with error page
setAttribute(sb, "Exception", e);
throw new RuntimeException("TradeServletAction.doPortfolio(...)"
+ " exception user =" + userID, e);
}
}
/**
* Retrieve the current Quote for the given stock symbol Dispatch to the
* Trade Quote JSP for display
*
*/
void doQuotes(StringBuilder sb, String userID, String symbols)
throws RuntimeException, IOException {
String results = "";
setAttribute(sb, "Page", "Quotes");
// Edge Caching:
// Getting Quotes has been moved to the JSP
// Quote.jsp. This makes each Quote a
// standalone "fragment", and thus is a candidate for
// Edge caching.
//
// requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.QUOTE_PAGE));
try {
Collection<OrderDataBean> closedOrders = getClosedOrders(userID);
// quote.jsp displays closed orders
if (closedOrders.size() > 0) {
setAttribute(sb, "closedOrders", closedOrders);
} else {
results = results + ". You have no closed orders.";
}
// quote.jsp displays quotes for the given symbol(s)
setAttribute(sb, "symbols", symbols);
QuoteDataBean quote = getQuote(symbols);
setAttribute(sb, "quote", quote);
} catch (Exception e) {
// log the exception with error page
setAttribute(sb, "Exception", e);
throw new RuntimeException("TradeServletAction.doQuotes(...)"
+ " exception user =" + userID + ", symbols=" + symbols, e);
}
}
/**
* Register a new trader given the provided user Profile information such as
* address, email, etc. Dispatch to the Trade Home JSP for display
*
*/
void doRegister(StringBuilder sb, String userID, String passwd,
String cpasswd, String fullname, String ccn,
String openBalanceString, String email, String address)
throws RuntimeException, IOException {
String results = "";
setAttribute(sb, "Page", "Register");
try {
// Validate user passwords match and are at least 1 char in length
if ((passwd.equals(cpasswd)) && (passwd.length() >= 1)) {
AccountDataBean accountData = register(userID, passwd,
fullname, address, email, ccn, new BigDecimal(
openBalanceString));
if (accountData == null) {
results = "Registration operation failed;";
setAttribute(sb, "results", results);
// requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.REGISTER_PAGE));
} else {
doLogin(sb, userID, passwd);
results = "Registration operation succeeded; Account "
+ accountData.getAccountID() + " has been created.";
setAttribute(sb, "results", results);
}
} else {
// Password validation failed
results = "Registration operation failed, your passwords did not match";
System.out.println(results);
setAttribute(sb, "results", results);
// requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.REGISTER_PAGE));
}
} catch (Exception e) {
// log the exception with error page
setAttribute(sb, "Exception", e);
throw new RuntimeException("TradeServletAction.doRegister(...)"
+ " exception user =" + userID, e);
}
}
/**
* Sell a current holding of stock shares for the given trader. Dispatch to
* the Trade Portfolio JSP for display
*
*/
void doSell(StringBuilder sb, String userID, Integer holdingID)
throws RuntimeException, IOException {
String results = "";
setAttribute(sb, "Page", "Sell");
try {
OrderDataBean orderData = sell(userID, holdingID, TradeConfig.orderProcessingMode);
setAttribute(sb, "orderData", orderData);
setAttribute(sb, "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
setAttribute(sb, "Exception", e);
} catch (Exception e) {
// log the exception with error page
setAttribute(sb, "Exception", e);
throw new RuntimeException("TradeServletAction.doSell(...)"
+ " exception selling holding " + holdingID + " for user ="
+ userID, e);
}
// requestDispatch(ctx, req, resp, userID, TradeConfig.getPage(TradeConfig.ORDER_PAGE));
}
void doWelcome(StringBuilder sb, String status) throws RuntimeException,
IOException {
setAttribute(sb, "Page", "Welcome");
setAttribute(sb, "results", status);
// requestDispatch(ctx, req, resp, null, TradeConfig.getPage(TradeConfig.WELCOME_PAGE));
}
/*
private void requestDispatch(ServletContext ctx, HttpServletRequest req,
HttpServletResponse resp, String userID, String page)
throws RuntimeException, IOException {
ctx.getRequestDispatcher(page).include(req, resp);
}
*/
/*
private void sendRedirect(HttpServletResponse resp, String page)
throws RuntimeException, IOException {
resp.sendRedirect(resp.encodeRedirectURL(page));
}
*/
private void setAttribute(StringBuilder sb, String attribute, Object value) {
if (log != null && log.isTraceEnabled()) {
sb.append(attribute);
sb.append(" = ");
sb.append(value);
sb.append(System.getProperty("line.separator"));
}
}
}