ClientHandler.java
上传用户:dinglihq
上传日期:2013-02-04
资源大小:99958k
文件大小:11k
源码类别:

Java编程

开发平台:

Java

  1. package bible.jms;
  2. import java.util.*;
  3. import java.sql.*;
  4. import javax.jms.*;
  5. import javax.naming.*;
  6. import javax.transaction.UserTransaction;
  7. /**
  8.  * Class ClientHandler
  9.  *
  10.  *
  11.  * @author
  12.  * @version %I%, %G%
  13.  */
  14. public class ClientHandler {
  15.   // Unique client ID for
  16.   // database operations
  17.   private String clientID = null;
  18.   // Data structure describing a trade
  19.   private class Trade {
  20.     String clientID   = null;
  21.     String side       = null;
  22.     String ticker     = null;
  23.     int    shares     = 0;
  24.     double sharePrice = 0.0;
  25.   }
  26.   /**
  27.    * Constructor ClientHandler
  28.    *
  29.    *
  30.    */
  31.   public ClientHandler() {}
  32.   /**
  33.    * Constructor ClientHandler
  34.    *
  35.    *
  36.    * @param id
  37.    *
  38.    */
  39.   public ClientHandler(String id) {
  40.     clientID = id;
  41.   }
  42.   // Get the WebLogic server's context
  43.   /**
  44.    * Method getServerContext
  45.    *
  46.    *
  47.    * @return
  48.    *
  49.    */
  50.   public Context getServerContext() {
  51.     Context   ctx = null;
  52.     Hashtable ht  = new Hashtable();
  53.     ht.put(Context.INITIAL_CONTEXT_FACTORY,
  54.            "weblogic.jndi.WLInitialContextFactory");
  55.     ht.put(Context.PROVIDER_URL, "t3://localhost:7001");
  56.     try {
  57.       ctx = new InitialContext(ht);
  58.     } catch (NamingException e) {
  59.       e.printStackTrace();
  60.     } finally {
  61.       return ctx;
  62.     }
  63.   }
  64.   // Load the queue with a single trade:
  65.   // BUY 1000 shares BEAS at $30/share
  66.   /**
  67.    * Method loadQueue
  68.    *
  69.    *
  70.    */
  71.   public void loadQueue() {
  72.     Context                ctx                = null;
  73.     QueueConnectionFactory qConnectionFactory = null;
  74.     QueueConnection        qConnection        = null;
  75.     QueueSession           qSession           = null;
  76.     QueueSender            qSender            = null;
  77.     Queue                  q                  = null;
  78.     TextMessage            textMsg            = null;
  79.     try {
  80.       // Obtain references to JMS structures
  81.       qConnectionFactory =
  82.         (QueueConnectionFactory) getServerContext().lookup("BibleJMSFactory");
  83.       qConnection        = qConnectionFactory.createQueueConnection();
  84.       qSession           = qConnection.createQueueSession(false,
  85.         javax.jms.QueueSession.AUTO_ACKNOWLEDGE);
  86.       q                  = (Queue) getServerContext().lookup("BibleJMSQueue");
  87.       qSender            = qSession.createSender(q);
  88.       textMsg            = qSession.createTextMessage();
  89.       // Pass a human-readable trade summary
  90.       // in the message's body
  91.       textMsg.clearBody();
  92.       textMsg.setText("BUY 1000 BEAS 30.0");
  93.       // Pass essential trade data in
  94.       // user-defined message properties
  95.       textMsg.setStringProperty("client_id", clientID);
  96.       textMsg.setStringProperty("side", "BUY");
  97.       textMsg.setStringProperty("ticker", "BEAS");
  98.       textMsg.setIntProperty("shares", 1000);
  99.       textMsg.setDoubleProperty("sharePrice", 30.0);
  100.       // Send the message
  101.       qSender.send(textMsg);
  102.     } catch (Exception e) {
  103.       e.printStackTrace();
  104.     } finally {
  105.       try {
  106.         if (qSender != null) {
  107.           qSender.close();
  108.         }
  109.         if (qSession != null) {
  110.           qSession.close();
  111.         }
  112.         if (qConnection != null) {
  113.           qConnection.close();
  114.         }
  115.       } catch (Exception e) {}
  116.     }
  117.   }
  118.   // Synchronously read a single trade from
  119.   // the queue for the given client
  120.   /**
  121.    * Method getNextTrade
  122.    *
  123.    *
  124.    * @return
  125.    *
  126.    * @throws Exception
  127.    *
  128.    */
  129.   public Trade getNextTrade() throws Exception {
  130.     QueueConnectionFactory qConnectionFactory = null;
  131.     QueueConnection        qConnection        = null;
  132.     QueueSession           qSession           = null;
  133.     QueueReceiver          qReceiver          = null;
  134.     Queue                  q                  = null;
  135.     Trade                  trade              = null;
  136.     try {
  137.       // Obtain references to JMS structures
  138.       qConnectionFactory =
  139.         (QueueConnectionFactory) getServerContext().lookup("BibleJMSFactory");
  140.       qConnection        = qConnectionFactory.createQueueConnection();
  141.       qSession           = qConnection.createQueueSession(false,
  142.         javax.jms.QueueSession.AUTO_ACKNOWLEDGE);
  143.       q                  = (Queue) getServerContext().lookup("BibleJMSQueue");
  144.       // Note the use of a message filter - we
  145.       // only want the next trade for the client
  146.       // represented by this ClientHandler instance
  147.       qReceiver = qSession.createReceiver(q, "client_id = '" + clientID
  148.                                           + "'");
  149.       // Start the connection
  150.       qConnection.start();
  151.       // Grab the next trade, if there is one,
  152.       // and copy its data from the message
  153.       // properties to a Trade data structure
  154.       TextMessage textMsg = (TextMessage) qReceiver.receiveNoWait();
  155.       if (textMsg != null) {
  156.         trade            = new Trade();
  157.         trade.clientID   = clientID;
  158.         trade.side       = textMsg.getStringProperty("side");
  159.         trade.ticker     = textMsg.getStringProperty("ticker");
  160.         trade.shares     = textMsg.getIntProperty("shares");
  161.         trade.sharePrice = textMsg.getDoubleProperty("sharePrice");
  162.       }
  163.       // Stop the connection
  164.       qConnection.stop();
  165.     } catch (Exception e) {
  166.       throw e;
  167.     } finally {
  168.       try {
  169.         if (qReceiver != null) {
  170.           qReceiver.close();
  171.         }
  172.         if (qSession != null) {
  173.           qSession.close();
  174.         }
  175.         if (qConnection != null) {
  176.           qConnection.close();
  177.         }
  178.       } catch (Exception e) {}
  179.       return trade;
  180.     }
  181.   }
  182.   // Update the cash balance remaining in
  183.   // the client's account. Account data is
  184.   // stored in an Oracle table. For simplicity,
  185.   // this code handles BUY transactions only.
  186.   /**
  187.    * Method updateAccountBalance
  188.    *
  189.    *
  190.    * @param trade
  191.    *
  192.    * @throws Exception
  193.    *
  194.    */
  195.   public void updateAccountBalance(Trade trade) throws Exception {
  196.     javax.sql.DataSource ds         = null;
  197.     java.sql.Connection  conn       = null;
  198.     PreparedStatement    statement1 = null;
  199.     PreparedStatement    statement2 = null;
  200.     String               sql        = null;
  201.     double               balance    = 0.0;
  202.     try {
  203.       // Obtain a JDBC connection from a transaction-enabled
  204.       // DataSource. I'm using the Oracle OCI driver
  205.       // with two-phase commit enabled, rather than
  206.       // the Oracle XA driver.
  207.       ds   =
  208.         (javax.sql.DataSource) getServerContext()
  209.           .lookup("OracleTxDataSource");
  210.       conn = ds.getConnection();
  211.       // Execute a query to obtain the client's current
  212.       // account balance from the database.
  213.       sql        = "SELECT BALANCE FROM ACCOUNT WHERE CLIENT_ID = ?";
  214.       statement1 = conn.prepareStatement(sql);
  215.       statement1.setString(1, clientID);
  216.       ResultSet resultSet = statement1.executeQuery();
  217.       if (resultSet.next()) {
  218.         balance = resultSet.getDouble(1);
  219.       } else {
  220.         Exception ex = new Exception("No such account");
  221.         throw ex;
  222.       }
  223.       // Calculate the cash required to buy the stock
  224.       double cost = trade.sharePrice * trade.shares;
  225.       // If the client has enough money, deduct the
  226.       // cost from their account balance and update
  227.       // their account in the database.
  228.       if (balance > cost) {
  229.         balance    -= cost;
  230.         sql        = "UPDATE ACCOUNT SET BALANCE = ? "
  231.                      + "WHERE CLIENT_ID = ?";
  232.         statement2 = conn.prepareStatement(sql);
  233.         statement2.setDouble(1, balance);
  234.         statement2.setString(2, clientID);
  235.         if (statement2.executeUpdate() != 1) {
  236.           Exception ex = new Exception("Error updating account balance");
  237.           throw ex;
  238.         }
  239.       } else {
  240.         Exception ex = new Exception("Insufficient funds");
  241.         throw ex;
  242.       }
  243.     } catch (Exception e) {
  244.       e.printStackTrace();
  245.       throw e;
  246.     } finally {
  247.       statement1.close();
  248.       statement2.close();
  249.       conn.close();
  250.     }
  251.   }
  252.   // Add an entry for stock purchased to
  253.   // the client's portfolio, which is stored
  254.   // in an Oracle table.
  255.   /**
  256.    * Method updatePortfolio
  257.    *
  258.    *
  259.    * @param trade
  260.    *
  261.    * @throws Exception
  262.    *
  263.    */
  264.   public void updatePortfolio(Trade trade) throws Exception {
  265.     javax.sql.DataSource ds        = null;
  266.     java.sql.Connection  conn      = null;
  267.     PreparedStatement    statement = null;
  268.     String               sql       = null;
  269.     try {
  270.       // Obtain a JDBC connection from a transaction-enabled
  271.       // DataSource. I'm using the Oracle OCI driver
  272.       // with two-phase commit enabled, rather than
  273.       // the Oracle XA driver.
  274.       ds   =
  275.         (javax.sql.DataSource) getServerContext()
  276.           .lookup("OracleTxDataSource");
  277.       conn = ds.getConnection();
  278.       // Execute a query to insert the client's stock
  279.       // purchase into the portfolio table.
  280.       sql       = "INSERT INTO PORTFOLIO "
  281.                   + "(CLIENT_ID, SIDE, TICKER, SHARES, PRICE) "
  282.                   + "VALUES (?, ?, ?, ?, ?)";
  283.       statement = conn.prepareStatement(sql);
  284.       statement.setString(1, clientID);
  285.       statement.setString(2, trade.side);
  286.       statement.setString(3, trade.ticker);
  287.       statement.setInt(4, trade.shares);
  288.       statement.setDouble(5, trade.sharePrice);
  289.       if (statement.executeUpdate() != 1) {
  290.         Exception ex = new Exception("Error updating client's portfolio");
  291.         throw ex;
  292.       }
  293.     } catch (Exception e) {
  294.       e.printStackTrace();
  295.       throw e;
  296.     } finally {
  297.       statement.close();
  298.       conn.close();
  299.     }
  300.   }
  301.   // Method to test our example
  302.   /**
  303.    * Method main
  304.    *
  305.    *
  306.    * @param args
  307.    *
  308.    */
  309.   public static void main(String[] args) {
  310.     UserTransaction tx = null;
  311.     try {
  312.       // Create a ClientHandler instance for fictitious
  313.       // customer "joe." Load the queue with a hard-coded
  314.       // trade for this client.
  315.       ClientHandler ch = new ClientHandler("joe");
  316.       ch.loadQueue();
  317.       // Obtain a reference to WebLogic Server's context.
  318.       // Use it to perform a JNDI lookup on the server's
  319.       // UserTransaction object.
  320.       Context ctx = ch.getServerContext();
  321.       tx = (UserTransaction) ctx.lookup("javax.transaction.UserTransaction");
  322.       // Begin the transaction
  323.       tx.begin();
  324.       // Grab the trade from the message queue
  325.       Trade trade = ch.getNextTrade();
  326.       // Update the client's account balance
  327.       ch.updateAccountBalance(trade);
  328.       // Update the client's portfolio
  329.       ch.updatePortfolio(trade);
  330.       // If no exceptions, commit the transaction
  331.       tx.commit();
  332.     } catch (Exception e) {
  333.       try {
  334.         // Something went wrong... roll back
  335.         // the transaction
  336.         tx.rollback();
  337.       } catch (Exception ee) {
  338.         ee.printStackTrace();
  339.       }
  340.     }
  341.   }
  342. }
  343. /*--- Formatted in Bible Style on Thu, Sep 6, '01 ---*/
  344. /*------ Formatted by Jindent 3.24 Gold 1.02 --- http://www.jindent.de ------*/