package examples.ejb.basic.statefulSession; import javax.ejb.*; import java.io.Serializable; import java.rmi.RemoteException; import java.util.*; /** * TraderBean is a stateful SessionBean. This EJBean illustrates: * * * @author Copyright (c) 1998 by WebLogic, Inc. All Rights Reserved. * @author Copyright (c) 1998-1999 by BEA WebXpress. All Rights Reserved. */ public class TraderBean implements SessionBean { static final boolean VERBOSE = true; // ----------------------------------------------------------------- // private variables private transient Hashtable stockPrices; private transient SessionContext ctx; private transient Properties props; // The reason the following attribute is public is to test // passivation into a persistent store, because the deployment descriptor // says it should be a stateful session bean. // This and the ejbCreate method in this file are the differences // between the examples in the stateful and stateless directories. public String traderName; public double tradingBalance; // ----------------------------------------------------------------- // SessionBean implementation /** * This method is required by the EJB Specification, * but is not used by this example. * */ public void ejbActivate() { if (VERBOSE) System.out.println("ejbActivate called"); } /** * This method is required by the EJB Specification, * but is not used by this example. * */ public void ejbRemove() { if (VERBOSE) System.out.println("ejbRemove called"); } /** * This method is required by the EJB Specification, * but is not used by this example. * */ public void ejbPassivate() { if (VERBOSE) System.out.println("ejbPassivate (" + traderName + ")"); } /** * Sets the session context. * * @param ctx SessionContext Context for session */ public void setSessionContext(SessionContext ctx) { if (VERBOSE) System.out.println("setSessionContext called"); this.ctx = ctx; props = ctx.getEnvironment(); } // Interface exposed to EJBObject (a clone of the Trader interface // without the RemoteExceptions) /** * This method corresponds to the create method in the home interface * "TraderHome.java". * The parameter sets of the two methods are identical. When the client calls * TraderHome.create(), the container allocates an instance of * the EJBean and calls ejbCreate(). * * @param traderName String Trader Name * @exception javax.ejb.CreateException * if there is a problem creating the bean * @see examples.ejb.basic.statefulSession.Trader */ public void ejbCreate(String traderName) throws CreateException { if (VERBOSE) System.out.println("ejbCreate (" + traderName + ")"); this.traderName = traderName; this.tradingBalance = 0.0; } /** * Buys shares of a stock for a named customer. * * @param customerName String Customer name * @param stockSymbol String Stock symbol * @param shares int Number of shares to buy * @return TradeResult Trade Result * @exception examples.ejb.basic.statefulSession.ProcessingErrorException * if there is an error while buying the shares */ public TradeResult buy(String customerName, String stockSymbol, int shares) throws ProcessingErrorException { if (VERBOSE && shares >= 0) { System.out.println("buy (" + customerName + ", " + stockSymbol + ", " + shares + ")"); } String str = null; try { int tradeLimit = getTradeLimit(); if (shares > tradeLimit) // limit for buying shares = tradeLimit; else if (shares < -tradeLimit) // limit for selling shares = -tradeLimit; double price = getStockPrice(stockSymbol); str = "insert into tradingorders " + "(traderName, account, stockSymbol, shares, price) VALUES (" + "'" + traderName + "','" + customerName + "','" + stockSymbol + "'," + shares + "," + + price + ")"; System.out.println("Executing transaction: " + str); tradingBalance = tradingBalance - (shares * price); // subtract purchases from cash account if (shares < 0) shares = -shares; return new TradeResult(shares, price); } catch (Exception e) { throw new ProcessingErrorException("Trader error: " + e); } } /** * Sells shares of a stock for a named customer. * * @param customerName String Customer name * @param stockSymbol String Stock symbol * @param shares int Number of shares to buy * @return TradeResult Trade Result * @exception examples.ejb.basic.statefulSession.ProcessingErrorException * if there is an error while selling the shares */ public TradeResult sell(String customerName, String stockSymbol, int shares) throws ProcessingErrorException { if (VERBOSE) { System.out.println("sell (" + customerName + ", " + stockSymbol + ", " + shares + ")"); } // convert "sell 100 shares" to "buy -100 shares" return buy(customerName, stockSymbol, -shares); } // The following routines illustrate getting information // from the environment. /** * Returns the name of this Trader. * * @return String traderName */ public String getTraderName() { return this.traderName; } /** * Returns the current balance of a trading session. * * @return double Balance */ public double getBalance() { return this.tradingBalance; } /** * Returns the trading limit. * * @return int Trading limit */ private int getTradeLimit() { return Integer.parseInt((String)props.get("tradeLimit")); } /** * Returns the stock price for a given stock. * * @param stockSymbol String Stock symbol * @return double Stock price * @exception examples.ejb.basic.statefulSession.ProcessingErrorException * if there is an error while checking the price */ public double getStockPrice(String stockSymbol) throws ProcessingErrorException { if (stockPrices == null) { stockPrices = (Hashtable) props.get("StockPrices"); } String priceStr = (String)stockPrices.get(stockSymbol); if (priceStr == null) throw new ProcessingErrorException ("Stock symbol " + stockSymbol + " does not exist"); return Double.valueOf(priceStr).doubleValue(); } }