KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > stockonline > ejb > session > stateless > broker > BrokerBean


1 /*
2  * StockOnline: EJB 1.1 Benchmark.
3  *
4  * Copyright © Commonwealth Scientific and Industrial Research Organisation (CSIRO - www.csiro.au), Australia 2001, 2002, 2003.
5  *
6  * Contact: Paul.Brebner@csiro.au
7  *
8  * This library is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or any
11  * later version.
12  *
13  * This library is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
16  * for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this library; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21  *
22  * Originally developed for the CSIRO Middleware Technology Evaluation (MTE) Project, by
23  * the Software Architectures and Component Technologies Group, CSIRO Mathematical and Information Sciences
24  * Canberra and Sydney, Australia
25  *
26  * www.cmis.csiro.au/sact/
27  * www.cmis.csiro.au/adsat/mte.htm
28  *
29  * Initial developer(s): Shiping Chen, Paul Brebner, Lei Hu, Shuping Ran, Ian Gorton, Anna Liu.
30  * Contributor(s): ______________________.
31  */

32
33
34 //
35
//
36
// History:
37
// 10/08/2001 Shiping Initial coding based on the existing code
38
//
39
// 26/11/2001 Shiping Change to avoide application excpetions:
40
// If an account's credit is not enough, still keep going.
41
//
42
//
43
//
44

45 package stockonline.ejb.session.stateless.broker;
46
47 import java.rmi.*;
48 import java.util.*;
49 import java.sql.*;
50
51 import javax.sql.*;
52 import javax.ejb.*;
53 import javax.naming.*;
54 import javax.rmi.PortableRemoteObject JavaDoc;
55
56 import stockonline.util.*; // common stuff shared between clients and EJB servers
57
import stockonline.ejb.session.interf.*; // stockonline public interfaces
58
import stockonline.ejb.sql.*; // SQL stuff in EJB servers
59

60
61 /** This class implements the business logic for the Stockonline application.
62 */

63
64 public class BrokerBean implements SessionBean
65 {
66     // Internal constances
67
//
68
final static boolean verbose = false;
69     final static String JavaDoc BEAN_NAME = "statelessBroker";
70       final static String JavaDoc RESOURCE_NAME = "java:comp/env/jdbc/StockDB";
71
72     protected SessionContext ctx = null;
73     private DataSource ds = null;
74     private Account account = new Account();
75     private StockItem stock = new StockItem();
76     private StockHolding holding = new StockHolding();
77     private StockTx transaction = new StockTx();
78
79     private boolean timing = false;
80     private stockonline.util.Timer timer = new stockonline.util.Timer();
81     private stockonline.util.ResultLog buyLog = new stockonline.util.ResultLog();
82     private stockonline.util.ResultLog sellLog = new stockonline.util.ResultLog();
83     private stockonline.util.ResultLog updateLog = new stockonline.util.ResultLog();
84     private stockonline.util.ResultLog createLog = new stockonline.util.ResultLog();
85     private stockonline.util.ResultLog queryIDLog = new stockonline.util.ResultLog();
86     private stockonline.util.ResultLog queryCodeLog = new stockonline.util.ResultLog();
87     private stockonline.util.ResultLog getHoldingLog = new stockonline.util.ResultLog();
88
89     // ----------------
90
// Business methods
91
//-----------------
92

93     /** To create a new account
94     * @param name The name of the account owner
95     * @param address The address of the account owner
96     * @param credit The initial credit in the account
97     * @return The iditifier of the new account
98     */

99     public int newAccount(String JavaDoc name, String JavaDoc address, int credit)
100         throws Exception JavaDoc
101     {
102         if(verbose) print("newAccount(" + name + ", " + address + ", " + credit + ") called");
103
104         try
105         {
106             if(timing) timer.start();
107
108             int accountID = newAccount_Imp(name, address, credit);
109
110             if(timing)
111             {
112                 timer.stop();
113                 if(verbose) timer.printTime("createTime = ");
114                 createLog.addSample(timer.getTime());
115             }
116
117             // To test transaction rollback:
118
// only the accounts with even account numbers should be created.
119
//
120
// if(accountID%2==1) throw new Exception("To test rollback of a transaction");
121

122             return accountID;
123         }
124         catch(Exception JavaDoc ex)
125         {
126             System.err.println("Exception in newAccount(): " + ex.toString());
127
128             try
129             {
130                 if(verbose) print("To rollback");
131                 ctx.setRollbackOnly();
132             }
133             catch(Exception JavaDoc e)
134             {
135                 System.err.println("Fail to rollback in newAccount(), due to " + e.toString());
136             }
137             throw ex;
138         }
139     }
140
141     /** To query a stock's prices by its ID
142     * @param stockID The iditifer of the stock (1-3000)
143     * @return An object which wraps the stock prices
144     */

145     public QueryResult queryStockValueByID(int stockID)
146         throws Exception JavaDoc
147     {
148         if(verbose) print("queryStockValueByID(" + stockID + ") called");
149
150         try
151         {
152             if(timing) timer.start();
153
154             QueryResult prices = queryStockValueByID_Imp(stockID);
155
156             if(timing)
157             {
158                 timer.stop();
159                 if(verbose) timer.printTime("queryIDTime = ");
160                 queryIDLog.addSample(timer.getTime());
161             }
162
163             return prices;
164         }
165         catch(Exception JavaDoc ex)
166         {
167             System.err.println("Exception in queryStockValueByID(): " + ex.toString());
168
169             try
170             {
171                 if(verbose) print("To rollback");
172                 ctx.setRollbackOnly();
173             }
174             catch(Exception JavaDoc e)
175             {
176                 System.err.println("Fail to rollback in queryStockValueByID(), due to " + e.toString());
177             }
178             throw ex;
179         }
180     }
181
182     /** To query a stock's prices by its Code
183     * @param stockCode The code of the stock (C1-C3000)
184     * @return An object which wraps the stock prices
185     */

186 /*
187     public QueryResult queryStockValueByCode(String stockCode)
188         throws Exception
189     {
190         if(verbose) print("queryStockValueByCode(" + stockCode + ") called");
191
192         try
193         {
194             if(timing) timer.start();
195             QueryResult prices = queryStockValueByCode_Imp(stockCode);
196             if(timing)
197             {
198                 timer.stop();
199                 if(verbose) timer.printTime("queryCodeTime = ");
200                 queryCodeLog.addSample(timer.getTime());
201             }
202
203             return prices;
204         }
205         catch(Exception ex)
206         {
207             System.err.println("Exception in queryStockValueByCode(): " + ex.toString());
208
209             try
210             {
211                 if(verbose) print("To rollback");
212                 ctx.setRollbackOnly();
213             }
214             catch(Exception e)
215             {
216                 System.err.println("Fail to rollback in queryStockValueByCode(), due to " + e.toString());
217             }
218             throw ex;
219         }
220     }
221 */

222     /** To buy amount of a stock
223     * @param accountID The iditifier of the acccount
224     * @param stockID The iditifier of the stock
225     * @param amount The amount of the stock to buy
226     */

227     public void buyStock(int accountID, int stockID, int amount)
228         throws Exception JavaDoc
229     {
230         if(verbose) print("buyStock(" + accountID + ", " + stockID + ", " + amount + ") called");
231
232         try
233         {
234             if(timing) timer.start();
235             int txID = buyStock_Imp(accountID, stockID, amount);
236             if(timing)
237             {
238                 timer.stop();
239                 if(verbose) timer.printTime("buyTime = ");
240                 buyLog.addSample(timer.getTime());
241             }
242
243             return;
244         }
245         catch(Exception JavaDoc ex)
246         {
247             System.err.println("Exception in buyStock(): " + ex.toString());
248
249             try
250             {
251                 if(verbose) print("To rollback");
252                 ctx.setRollbackOnly();
253             }
254             catch(Exception JavaDoc e)
255             {
256                 System.err.println("Fail to rollback in buyStock(), due to " + e.toString());
257             }
258             throw ex;
259         }
260     }
261
262     /** To buy amount of a stock
263     * @param accountID The iditifier of the acccount
264     * @param stockID The iditifier of the stock
265     * @param amount The amount of the stock to sell
266     */

267     public void sellStock(int accountID, int stockID, int amount)
268         throws Exception JavaDoc
269     {
270         if(verbose) print("sellStock(" + accountID + ", " + stockID + ", " + amount + ") called");
271
272         try
273         {
274             if(timing) timer.start();
275             int txID = sellStock_Imp(accountID, stockID, amount);
276             if(verbose) print("buyStock()......OK: return txID = " + txID);
277             if(timing)
278             {
279                 timer.stop();
280                 if(verbose) timer.printTime("sellTime = ");
281                 sellLog.addSample(timer.getTime());
282             }
283
284             return;
285         }
286         catch(Exception JavaDoc ex)
287         {
288             System.err.println("Exception in sellStock(): " + ex.toString());
289
290             try
291             {
292                 if(verbose) print("To rollback");
293                 ctx.setRollbackOnly();
294             }
295             catch(Exception JavaDoc e)
296             {
297                 System.err.println("Fail to rollback in sellStock(), due to " + e.toString());
298             }
299             throw ex;
300         }
301     }
302
303     /** To update the credit of an account
304     * @param accountID The iditifier of the acccount
305     * @param credit The credit to be increased or decreased (-)
306     */

307     public void updateAccount(int accountID, int credit)
308         throws Exception JavaDoc
309     {
310         if(verbose) print("updataAccount(" + accountID + ", " + credit + ")");
311
312         try
313         {
314             if(timing) timer.start();
315             updateAccount_Imp(accountID, credit);
316             if(timing)
317             {
318                 timer.stop();
319                 if(verbose) timer.printTime("updayeTime = ");
320                 updateLog.addSample(timer.getTime());
321             }
322
323             if(verbose) print("updataAccount()......OK: return void");
324         }
325         catch(Exception JavaDoc ex)
326         {
327             System.err.println("Exception in updateAccount(): " + ex.toString());
328
329             try
330             {
331                 if(verbose) print("To rollback");
332                 ctx.setRollbackOnly();
333             }
334             catch(Exception JavaDoc e)
335             {
336                 System.err.println("Fail to rollback in updateAccount(), due to " + e.toString());
337             }
338             throw ex;
339         }
340     }
341
342     /** To get current stock holding statement for an account
343     * @param accountID The iditifier of the acccount
344     * @param start_stockID The stockID from which the list starts, default is 0
345     * @return A set of objects of Holding class, which wraps the holding information.
346     * @see stockonline.util.Holding
347     */

348     public Collection getHoldingStatement(int accountID, int start_stockID)
349         throws Exception JavaDoc
350     {
351         if(verbose) print("getHoldingStatement(" + accountID + ")");
352
353         try
354         {
355             if(timing) timer.start();
356             Collection list = getHoldingStatement_Imp (accountID, start_stockID);
357             if(timing)
358             {
359                 timer.stop();
360                 if(verbose) timer.printTime("getHoldingTime = ");
361                 getHoldingLog.addSample(timer.getTime());
362             }
363
364             return list;
365         }
366         catch(Exception JavaDoc ex)
367         {
368             System.err.println("Exception in updateAccount(): " + ex.toString());
369
370             try
371             {
372                 if(verbose) print("To rollback");
373                 ctx.setRollbackOnly();
374             }
375             catch(Exception JavaDoc e)
376             {
377                 System.err.println("Fail to rollback in updateAccount(), due to " + e.toString());
378             }
379             throw ex;
380         }
381     }
382
383     /** This method provides an interface for clients and servers to communicate each other
384     * @param msg The command
385     * @return The expected message in a string
386     */

387     public Collection cmdChannel(CmdMessage msg)
388         throws Exception JavaDoc
389     {
390         if(verbose) print("cmdChannel(" + msg.cmd + ") called");
391
392         ArrayList list = new ArrayList();
393
394         switch(msg.cmd)
395         {
396         case CmdMessage.SET_TIMING_ON:
397             if(verbose) System.out.println("SET_TIMING_ON");
398             timing = true;
399             break;
400         case CmdMessage.SET_TIMING_OFF:
401             if(verbose) System.out.println("SET_TIMING_OFF");
402             timing = false;
403             break;
404         case CmdMessage.GET_TIMING_LOG:
405             if(verbose) System.out.println("GET_TIMING_LOG");
406
407             list.add(buyLog);
408             list.add(sellLog);
409             list.add(createLog);
410             list.add(updateLog);
411             list.add(queryIDLog);
412             list.add(queryCodeLog);
413             list.add(getHoldingLog);
414
415             if(verbose) System.out.println("GET_TIMING_LOG");
416             break;
417         case CmdMessage.RESET_DATABASE:
418             if(verbose) System.out.println("RESET_DATABASE");
419             DBLoad.resetOracleDB(ds);
420             break;
421         default:
422             System.err.println("invalid cmd message");
423             break;
424         }
425         
426         return list;
427     }
428
429     /** To create a new account for rollbacktest
430     * @param name The name of the account owner
431     * @param address The address of the account owner
432     * @param credit The initial credit in the account
433     * @return The iditifier of the new account
434     */

435     public int newAccountForTestRollback(String JavaDoc name, String JavaDoc address, int credit)
436         throws Exception JavaDoc
437     {
438         if(verbose) print("newAccountForTestRollback(" + name + ", " + address + ", " + credit + ") called");
439         int accountID = 0;
440
441         try
442         {
443             accountID = newAccount_Imp(name, address, credit);
444             if(verbose) print("accountID = " + accountID);
445
446             if(verbose) System.out.println("To rollback");
447             ctx.setRollbackOnly();
448         }
449         catch(Exception JavaDoc ex)
450         {
451             System.err.println(BEAN_NAME + " Exception: " + ex.getMessage());
452         }
453         finally
454         {
455             return accountID;
456         }
457     }
458
459     /** To test rollback
460     * @param accountID The iditifier of account
461     * @return true = rollback sucessful; false = rollback unsucessful
462     */

463     public boolean testRollback(int accountID)
464         throws Exception JavaDoc
465     {
466         if(verbose) print("testRollBack() called");
467         boolean testPass = false;
468         
469         try
470         {
471             float credit = getCurrentCredit_Imp(accountID);
472             testPass = false;
473             if(verbose) System.out.println("Test failed !");
474         }
475         catch(Exception JavaDoc e)
476         {
477             testPass = true;
478             if(verbose) System.out.println("Test Passed !");
479         }
480         
481         return testPass;
482     }
483
484     //-----------------------------------------------
485
// Internal methods
486
//-----------------------------------------------
487

488     private int newAccount_Imp(String JavaDoc name, String JavaDoc address, int credit)
489         throws Exception JavaDoc
490     {
491         if(verbose) print("newAccount_Imp(" + name + ", " + address + ", " + credit + ") called");
492
493         Connection con = ds.getConnection();
494
495         try
496         {
497             int accountID = account.createAccount(con, name, address, credit);
498             return accountID;
499         }
500         catch(Exception JavaDoc ex)
501         {
502             System.err.println(BEAN_NAME + " Exception: " + ex.getMessage());
503             throw ex;
504         }
505         finally
506         {
507             con.close();
508         }
509     }
510
511     private float getCurrentCredit_Imp(int accountID)
512         throws Exception JavaDoc
513     {
514         if(verbose) print("getCurrentCredit_Imp(" + accountID + ") called");
515
516         Connection con = ds.getConnection();
517
518         try
519         {
520             float credit = account.getCredit(con, accountID);
521             return credit;
522         }
523         catch(Exception JavaDoc ex)
524         {
525             System.err.println(BEAN_NAME + " Exception: " + ex.getMessage());
526             throw ex;
527         }
528         finally
529         {
530             con.close();
531         }
532     }
533
534     private void updateAccount_Imp(int accountID, int credit)
535         throws Exception JavaDoc
536     {
537         if(verbose) print("nupdateAccount_Imp(" + accountID + ", " + credit + ") called");
538
539         Connection con = ds.getConnection();
540
541         try
542         {
543             account.updateCredit(con, accountID, credit);
544         }
545         catch(Exception JavaDoc ex)
546         {
547             System.err.println(BEAN_NAME + " Exception: " + ex.getMessage());
548             throw ex;
549         }
550         finally
551         {
552             con.close();
553         }
554     }
555
556     private QueryResult queryStockValueByID_Imp(int stockID)
557         throws Exception JavaDoc
558     {
559         if(verbose) print("queryStockValueByID_Imp(" + stockID + ") called");
560
561         Connection con = ds.getConnection();
562
563         try
564         {
565             QueryResult prices = stock.queryByID(con, stockID);
566             return prices;
567         }
568         catch(Exception JavaDoc ex)
569         {
570             System.err.println(BEAN_NAME + " Exception: " + ex.getMessage());
571             throw ex;
572         }
573         finally
574         {
575             con.close();
576         }
577     }
578
579     private QueryResult queryStockValueByCode_Imp(String JavaDoc stockCode)
580         throws Exception JavaDoc
581     {
582         if(verbose) print("queryStockValueByCode_Imp(" + stockCode + ") called");
583
584         Connection con = ds.getConnection();
585
586         try
587         {
588             QueryResult prices = stock.queryByCode(con, stockCode);
589             return prices;
590         }
591         catch(Exception JavaDoc ex)
592         {
593             System.err.println(BEAN_NAME + " Exception: " + ex.getMessage());
594             throw ex;
595         }
596         finally
597         {
598             con.close();
599         }
600     }
601
602     private int buyStock_Imp(int accountID, int stockID, int amount)
603         throws Exception JavaDoc
604     {
605         if(verbose) print("bugStock_Imp(" + accountID + ", " + stockID + ", " + amount + ") called");
606
607         // To get a connection
608
Connection con = ds.getConnection();
609
610         try
611         {
612             // Step 1. To check credit
613
// If the account does not have enough credit to buy,
614
// an exception will be thrown.
615
//
616
float credit = account.getCredit(con, accountID);
617             if(verbose) System.out.println("credit = $" + credit);
618
619             float current_val = stock.getCurrentPrice(con, stockID);
620             if(verbose) System.out.println("current_val = $" + current_val);
621
622             float payment = current_val * amount;
623             if(verbose) System.out.println("payment = $" + payment);
624
625             // if (credit < payment) // if the account cannot afford the buy
626
// throw new Exception("No enough credit for the buy transaction: accountID = " + accountID);
627

628             // Step 2. To update stockholding associated with this account
629
//
630
holding.updateForBuy(con, accountID, stockID, amount);
631
632             // Step 3. To update the account credit for the transaction.
633
// (Should do, but we do NOT do that currently)
634
//
635
// account.updateCredit(con, accountID, -payment);
636

637             // Step 4. To create the transaction record
638
//
639
int txID = transaction.create(con, "B", accountID, stockID, amount, current_val);
640
641             return txID;
642         }
643         catch (Exception JavaDoc ex)
644         {
645             System.err.println("Exception in BrokerBean.buyStock_Imp(): " + ex.getMessage());
646             throw ex;
647         }
648         finally
649         {
650             con.close();
651         }
652     }
653
654     private int sellStock_Imp(int accountID, int stockID, int amount)
655         throws Exception JavaDoc
656     {
657         if(verbose) print("sellStock_Imp(" + accountID + ", " + stockID + ", " + amount + ") called");
658
659         // To get a connection
660
Connection con = ds.getConnection();
661
662         try
663         {
664             // Step 2. To get current price
665
//
666
float currentPrice = stock.getCurrentPrice(con, stockID);
667             if(verbose) System.out.println("currentPrice = " + currentPrice);
668
669             // Step 1. To update stockholding associated with this account
670
// If the account does not hold or does not hold enough holding for sell,
671
// an exception will be thrown.
672
//
673
holding.updateForSell(con, accountID, stockID, amount);
674
675             // Step 3. To update the account credit for the transaction.
676
// (Should do, but we do NOT do that currently)
677
//
678
// float payment = currentPrice * amount;
679
// account.updateCredit(con, accountID, payment);
680

681             // Step 4. To create the transaction record
682
//
683
int txID = transaction.create(con, "S", accountID, stockID, amount, currentPrice);
684
685             return txID;
686         }
687         catch (Exception JavaDoc ex)
688         {
689             System.err.println("Exception in BrokerBean.sellStock_Imp(): " + ex.getMessage());
690             throw ex;
691         }
692         finally
693         {
694             con.close();
695         }
696     }
697
698     private Collection getHoldingStatement_Imp (int accountID, int start_stockID)
699         throws Exception JavaDoc
700     {
701         if(verbose) print("getHoldingStatement_Imp(" + accountID + ", " + start_stockID + ") called");
702
703         Connection con = ds.getConnection();
704
705         try
706         {
707             Collection list = holding.getHoldingList(con, accountID, start_stockID);
708             return list;
709         }
710         catch(Exception JavaDoc ex)
711         {
712             System.err.println(BEAN_NAME + " Exception: " + ex.getMessage());
713             throw ex;
714         }
715         finally
716         {
717             con.close();
718         }
719     }
720
721     // Print out a message with the current thread ID
722
//
723
private void print( String JavaDoc message )
724     {
725         System.out.println("[" + Thread.currentThread().getName() + "] " + message);
726     }
727
728     //-----------------------------------------------
729
// EJB-required methods.
730
//-----------------------------------------------
731

732     public void setSessionContext(SessionContext ctx)
733     {
734         this.ctx = ctx;
735     }
736
737     /** In this method, the datasource reference is obtained via JNDI.
738     */

739     public void ejbCreate()
740         throws CreateException
741     {
742         if(verbose) print("ejbCreate() called");
743
744         try
745         {
746             if(verbose) print("To get datasource: " + RESOURCE_NAME);
747             ds = (DataSource)(new InitialContext()).lookup(RESOURCE_NAME);
748         }
749         catch (javax.naming.NamingException JavaDoc ex)
750         {
751             System.err.println(BEAN_NAME + ".ejbCreate(): " + ex.toString());
752             // throw new CreateException(ex.toString());
753
}
754     }
755
756     public void ejbRemove() {}
757     public void ejbActivate() {}
758     public void ejbPassivate() {}
759 }
760
761
Popular Tags