ClientHandler.java
资源名称:某公司的java培训教材 [点击查看]
上传用户:dinglihq
上传日期:2013-02-04
资源大小:99958k
文件大小:11k
源码类别:
Java编程
开发平台:
Java
- package bible.jms;
- import java.util.*;
- import java.sql.*;
- import javax.jms.*;
- import javax.naming.*;
- import javax.transaction.UserTransaction;
- /**
- * Class ClientHandler
- *
- *
- * @author
- * @version %I%, %G%
- */
- public class ClientHandler {
- // Unique client ID for
- // database operations
- private String clientID = null;
- // Data structure describing a trade
- private class Trade {
- String clientID = null;
- String side = null;
- String ticker = null;
- int shares = 0;
- double sharePrice = 0.0;
- }
- /**
- * Constructor ClientHandler
- *
- *
- */
- public ClientHandler() {}
- /**
- * Constructor ClientHandler
- *
- *
- * @param id
- *
- */
- public ClientHandler(String id) {
- clientID = id;
- }
- // Get the WebLogic server's context
- /**
- * Method getServerContext
- *
- *
- * @return
- *
- */
- public Context getServerContext() {
- Context ctx = null;
- Hashtable ht = new Hashtable();
- ht.put(Context.INITIAL_CONTEXT_FACTORY,
- "weblogic.jndi.WLInitialContextFactory");
- ht.put(Context.PROVIDER_URL, "t3://localhost:7001");
- try {
- ctx = new InitialContext(ht);
- } catch (NamingException e) {
- e.printStackTrace();
- } finally {
- return ctx;
- }
- }
- // Load the queue with a single trade:
- // BUY 1000 shares BEAS at $30/share
- /**
- * Method loadQueue
- *
- *
- */
- public void loadQueue() {
- Context ctx = null;
- QueueConnectionFactory qConnectionFactory = null;
- QueueConnection qConnection = null;
- QueueSession qSession = null;
- QueueSender qSender = null;
- Queue q = null;
- TextMessage textMsg = null;
- try {
- // Obtain references to JMS structures
- qConnectionFactory =
- (QueueConnectionFactory) getServerContext().lookup("BibleJMSFactory");
- qConnection = qConnectionFactory.createQueueConnection();
- qSession = qConnection.createQueueSession(false,
- javax.jms.QueueSession.AUTO_ACKNOWLEDGE);
- q = (Queue) getServerContext().lookup("BibleJMSQueue");
- qSender = qSession.createSender(q);
- textMsg = qSession.createTextMessage();
- // Pass a human-readable trade summary
- // in the message's body
- textMsg.clearBody();
- textMsg.setText("BUY 1000 BEAS 30.0");
- // Pass essential trade data in
- // user-defined message properties
- textMsg.setStringProperty("client_id", clientID);
- textMsg.setStringProperty("side", "BUY");
- textMsg.setStringProperty("ticker", "BEAS");
- textMsg.setIntProperty("shares", 1000);
- textMsg.setDoubleProperty("sharePrice", 30.0);
- // Send the message
- qSender.send(textMsg);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (qSender != null) {
- qSender.close();
- }
- if (qSession != null) {
- qSession.close();
- }
- if (qConnection != null) {
- qConnection.close();
- }
- } catch (Exception e) {}
- }
- }
- // Synchronously read a single trade from
- // the queue for the given client
- /**
- * Method getNextTrade
- *
- *
- * @return
- *
- * @throws Exception
- *
- */
- public Trade getNextTrade() throws Exception {
- QueueConnectionFactory qConnectionFactory = null;
- QueueConnection qConnection = null;
- QueueSession qSession = null;
- QueueReceiver qReceiver = null;
- Queue q = null;
- Trade trade = null;
- try {
- // Obtain references to JMS structures
- qConnectionFactory =
- (QueueConnectionFactory) getServerContext().lookup("BibleJMSFactory");
- qConnection = qConnectionFactory.createQueueConnection();
- qSession = qConnection.createQueueSession(false,
- javax.jms.QueueSession.AUTO_ACKNOWLEDGE);
- q = (Queue) getServerContext().lookup("BibleJMSQueue");
- // Note the use of a message filter - we
- // only want the next trade for the client
- // represented by this ClientHandler instance
- qReceiver = qSession.createReceiver(q, "client_id = '" + clientID
- + "'");
- // Start the connection
- qConnection.start();
- // Grab the next trade, if there is one,
- // and copy its data from the message
- // properties to a Trade data structure
- TextMessage textMsg = (TextMessage) qReceiver.receiveNoWait();
- if (textMsg != null) {
- trade = new Trade();
- trade.clientID = clientID;
- trade.side = textMsg.getStringProperty("side");
- trade.ticker = textMsg.getStringProperty("ticker");
- trade.shares = textMsg.getIntProperty("shares");
- trade.sharePrice = textMsg.getDoubleProperty("sharePrice");
- }
- // Stop the connection
- qConnection.stop();
- } catch (Exception e) {
- throw e;
- } finally {
- try {
- if (qReceiver != null) {
- qReceiver.close();
- }
- if (qSession != null) {
- qSession.close();
- }
- if (qConnection != null) {
- qConnection.close();
- }
- } catch (Exception e) {}
- return trade;
- }
- }
- // Update the cash balance remaining in
- // the client's account. Account data is
- // stored in an Oracle table. For simplicity,
- // this code handles BUY transactions only.
- /**
- * Method updateAccountBalance
- *
- *
- * @param trade
- *
- * @throws Exception
- *
- */
- public void updateAccountBalance(Trade trade) throws Exception {
- javax.sql.DataSource ds = null;
- java.sql.Connection conn = null;
- PreparedStatement statement1 = null;
- PreparedStatement statement2 = null;
- String sql = null;
- double balance = 0.0;
- try {
- // Obtain a JDBC connection from a transaction-enabled
- // DataSource. I'm using the Oracle OCI driver
- // with two-phase commit enabled, rather than
- // the Oracle XA driver.
- ds =
- (javax.sql.DataSource) getServerContext()
- .lookup("OracleTxDataSource");
- conn = ds.getConnection();
- // Execute a query to obtain the client's current
- // account balance from the database.
- sql = "SELECT BALANCE FROM ACCOUNT WHERE CLIENT_ID = ?";
- statement1 = conn.prepareStatement(sql);
- statement1.setString(1, clientID);
- ResultSet resultSet = statement1.executeQuery();
- if (resultSet.next()) {
- balance = resultSet.getDouble(1);
- } else {
- Exception ex = new Exception("No such account");
- throw ex;
- }
- // Calculate the cash required to buy the stock
- double cost = trade.sharePrice * trade.shares;
- // If the client has enough money, deduct the
- // cost from their account balance and update
- // their account in the database.
- if (balance > cost) {
- balance -= cost;
- sql = "UPDATE ACCOUNT SET BALANCE = ? "
- + "WHERE CLIENT_ID = ?";
- statement2 = conn.prepareStatement(sql);
- statement2.setDouble(1, balance);
- statement2.setString(2, clientID);
- if (statement2.executeUpdate() != 1) {
- Exception ex = new Exception("Error updating account balance");
- throw ex;
- }
- } else {
- Exception ex = new Exception("Insufficient funds");
- throw ex;
- }
- } catch (Exception e) {
- e.printStackTrace();
- throw e;
- } finally {
- statement1.close();
- statement2.close();
- conn.close();
- }
- }
- // Add an entry for stock purchased to
- // the client's portfolio, which is stored
- // in an Oracle table.
- /**
- * Method updatePortfolio
- *
- *
- * @param trade
- *
- * @throws Exception
- *
- */
- public void updatePortfolio(Trade trade) throws Exception {
- javax.sql.DataSource ds = null;
- java.sql.Connection conn = null;
- PreparedStatement statement = null;
- String sql = null;
- try {
- // Obtain a JDBC connection from a transaction-enabled
- // DataSource. I'm using the Oracle OCI driver
- // with two-phase commit enabled, rather than
- // the Oracle XA driver.
- ds =
- (javax.sql.DataSource) getServerContext()
- .lookup("OracleTxDataSource");
- conn = ds.getConnection();
- // Execute a query to insert the client's stock
- // purchase into the portfolio table.
- sql = "INSERT INTO PORTFOLIO "
- + "(CLIENT_ID, SIDE, TICKER, SHARES, PRICE) "
- + "VALUES (?, ?, ?, ?, ?)";
- statement = conn.prepareStatement(sql);
- statement.setString(1, clientID);
- statement.setString(2, trade.side);
- statement.setString(3, trade.ticker);
- statement.setInt(4, trade.shares);
- statement.setDouble(5, trade.sharePrice);
- if (statement.executeUpdate() != 1) {
- Exception ex = new Exception("Error updating client's portfolio");
- throw ex;
- }
- } catch (Exception e) {
- e.printStackTrace();
- throw e;
- } finally {
- statement.close();
- conn.close();
- }
- }
- // Method to test our example
- /**
- * Method main
- *
- *
- * @param args
- *
- */
- public static void main(String[] args) {
- UserTransaction tx = null;
- try {
- // Create a ClientHandler instance for fictitious
- // customer "joe." Load the queue with a hard-coded
- // trade for this client.
- ClientHandler ch = new ClientHandler("joe");
- ch.loadQueue();
- // Obtain a reference to WebLogic Server's context.
- // Use it to perform a JNDI lookup on the server's
- // UserTransaction object.
- Context ctx = ch.getServerContext();
- tx = (UserTransaction) ctx.lookup("javax.transaction.UserTransaction");
- // Begin the transaction
- tx.begin();
- // Grab the trade from the message queue
- Trade trade = ch.getNextTrade();
- // Update the client's account balance
- ch.updateAccountBalance(trade);
- // Update the client's portfolio
- ch.updatePortfolio(trade);
- // If no exceptions, commit the transaction
- tx.commit();
- } catch (Exception e) {
- try {
- // Something went wrong... roll back
- // the transaction
- tx.rollback();
- } catch (Exception ee) {
- ee.printStackTrace();
- }
- }
- }
- }
- /*--- Formatted in Bible Style on Thu, Sep 6, '01 ---*/
- /*------ Formatted by Jindent 3.24 Gold 1.02 --- http://www.jindent.de ------*/