home *** CD-ROM | disk | FTP | other *** search
/ Internet News 1999 October / INEWS_10_CD.ISO / pc / jdk / jdk1.2.2 / docs / guide / rmi / examples / stock / StockServer.java < prev    next >
Encoding:
Java Source  |  1999-09-19  |  7.3 KB  |  238 lines

  1. /*
  2.  * Copyright (c) 1996,1997,1998,1999 Sun Microsystems, Inc. All Rights Reserved.
  3.  *
  4.  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
  5.  * modify and redistribute this software in source and binary code form,
  6.  * provided that i) this copyright notice and license appear on all copies of
  7.  * the software; and ii) Licensee does not utilize the software in a manner
  8.  * which is disparaging to Sun.
  9.  *
  10.  * This software is provided "AS IS," without a warranty of any kind. ALL
  11.  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
  12.  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  13.  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
  14.  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
  15.  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
  16.  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
  17.  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
  18.  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
  19.  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
  20.  * POSSIBILITY OF SUCH DAMAGES.
  21.  *
  22.  * This software is not designed or intended for use in on-line control of
  23.  * aircraft, air traffic, aircraft navigation or aircraft communications; or in
  24.  * the design, construction, operation or maintenance of any nuclear
  25.  * facility. Licensee represents and warrants that it will not use or
  26.  * redistribute the Software for such purposes.
  27.  */
  28.  
  29. package examples.stock;
  30.  
  31. import java.rmi.*;
  32. import java.rmi.server.*;
  33. import java.rmi.registry.LocateRegistry;
  34. import java.util.*;
  35.  
  36. public class StockServer extends UnicastRemoteObject
  37.     implements StockWatch, Runnable
  38. {
  39.     /** table that maps StockNotify objects to a vector of stocks */
  40.     private Hashtable notifyTable = new Hashtable();
  41.     /** table that maps stock names to stock update info */
  42.     private Hashtable stockTable = new Hashtable();
  43.     /** thread for notifying watchers of stock updates */
  44.     private Thread notifier = null;
  45.  
  46.     private static String name[] = { "Sun", "HP", "Microsoft", "Compaq", "Novell",
  47.                      "IBM", "Apple", "AOL", "Inprise", "SGI"};
  48.     /**
  49.      * Construct the stock server
  50.      * @exception RemoteException if remote object cannot be exported
  51.      */
  52.     public StockServer() throws RemoteException 
  53.     {
  54.     for (int i=0; i<name.length; i++) {
  55.         stockTable.put(name[i], new Stock(name[i]));
  56.     }
  57.     }
  58.  
  59.     /**
  60.      * Request notification of stock updates.
  61.      * @param stock the stock name
  62.      * @param obj the remote object to be notified
  63.      * @return the latest update of the stock
  64.      * @exception StockNotFoundException if stock is not known
  65.      */
  66.     public synchronized Stock watch(String stock, StockNotify obj)
  67.     throws StockNotFoundException
  68.     {
  69.     System.out.println("StockServer.watch: " + stock );
  70.     
  71.     if (!stockTable.containsKey(stock)) {
  72.         throw new StockNotFoundException(stock);
  73.     }
  74.     
  75.     Vector stocks = (Vector)notifyTable.get(obj);
  76.  
  77.     // register interested party...
  78.     if (stocks == null) {
  79.         stocks = new Vector();
  80.         notifyTable.put(obj, stocks);
  81.     }
  82.  
  83.     // add stock to list
  84.     if (!stocks.contains(stock)) {
  85.         stocks.addElement(stock);
  86.     }
  87.     
  88.     // start thread to notify watchers...
  89.     if (notifier == null) {
  90.         notifier = new Thread(this, "StockNotifier");
  91.         notifier.start();
  92.     }
  93.     return (Stock)stockTable.get(stock);
  94.     }
  95.  
  96.     /**
  97.      * Cancel request for stock updates for a particular stock.
  98.      * @param stock the stock name
  99.      * @param obj the remote object canceling the notification
  100.      */
  101.     public void cancel(String stock, StockNotify obj)
  102.     {
  103.     Vector stocks = (Vector)notifyTable.get(obj);
  104.     stocks.removeElement(stock);
  105.     }
  106.  
  107.    /**
  108.      * Returns an array of stock update information for the stocks
  109.      * already registered by the remote object.
  110.      * @param obj the remote object
  111.      * @return the list of stocks, or null if obj is not watching any
  112.      *  stocks
  113.      * @exception RemoteException if some communication failure occurs
  114.      */
  115.     public Stock[] list(StockNotify obj)
  116.     {
  117.     Vector stocks = (Vector)notifyTable.get(obj);
  118.     Stock[] stockList = null;
  119.     
  120.     if (stocks != null) {
  121.         Enumeration enum = stocks.elements();
  122.         stockList = new Stock[stocks.size()];
  123.         int i=0;
  124.         // collect updates to the stocks this watcher is
  125.         // interested in
  126.         while (enum.hasMoreElements()) {
  127.         String stockname = (String)enum.nextElement();
  128.         stockList[i++] = (Stock)stockTable.get(stockname);
  129.         }
  130.     }
  131.     return stockList;
  132.     }
  133.  
  134.     /**
  135.      * Cancel all requests for stock updates for the remote object.
  136.      * @param obj the remote object canceling the request
  137.      * @exception RemoteException if some communication failure occurs
  138.      */
  139.     public synchronized void cancelAll(StockNotify obj)
  140.     {
  141.     notifyTable.remove(obj);
  142.     }
  143.  
  144.     /**
  145.      * Private method to generate random stock updates
  146.      */
  147.     private void generateUpdates() 
  148.     {
  149.     Enumeration enum = stockTable.elements();
  150.     while (enum.hasMoreElements()) {
  151.         Stock stock = (Stock)enum.nextElement();
  152.         stock.update();
  153.     }
  154.     }
  155.  
  156.     /**
  157.      * The run method (called from the notifier thread) sends out stock
  158.      * updates periodically to those remote objects that have
  159.      * registered interest in being notified.
  160.      */
  161.     public void run() 
  162.     {
  163.     boolean done = false;
  164.  
  165.     do {
  166.   
  167.         try {
  168.         // wait for a few seconds between updates
  169.         Thread.currentThread().sleep(2000);
  170.         } catch (InterruptedException e) {
  171.         }
  172.  
  173.         Date date = new Date();
  174.         // update stocks in table
  175.         generateUpdates();
  176.         
  177.         // enumerate through each watcher...
  178.         Enumeration enum = notifyTable.keys();
  179.         while (enum.hasMoreElements()) {
  180.         StockNotify obj = (StockNotify)enum.nextElement();
  181.         Stock[] stockList = list(obj);
  182.         if (stockList != null) {
  183.             // send update
  184.             try {
  185.             System.out.println("StockServer.run: sending update " +
  186.                        date);
  187.             obj.update(date, stockList);
  188.             } catch (RemoteException e) {
  189.             // can't reach watcher; cancel notification request
  190.             System.out.println("StockServer.run: exception");
  191.             e.printStackTrace();
  192.             cancelAll(obj);
  193.             }
  194.         }
  195.         }
  196.  
  197.         // check to see if the update thread should exit
  198.         synchronized (this) {
  199.         if (notifyTable.isEmpty()) {
  200.             notifier = null;
  201.             done = true;
  202.         }
  203.         }
  204.  
  205.     } while (!done);
  206.     }
  207.  
  208.     /**
  209.      * Start up the stock server; also creates a registry so that the
  210.      * StockApplet can lookup the server.
  211.      */
  212.     public static void main(String args[]) 
  213.     {
  214.     // Create and install the security manager
  215.     System.setSecurityManager(new RMISecurityManager());
  216.  
  217.     try {
  218.         System.out.println("StockServer.main: creating registry");
  219.         LocateRegistry.createRegistry(2005);
  220.         System.out.println("StockServer.main: creating server");
  221.         StockServer server = new StockServer();
  222.         System.out.println("StockServer.main: binding server ");
  223.         Naming.rebind("//:2005/example.stock.StockServer", server);
  224.         System.out.println("StockServer.main: done");
  225.  
  226.         // Note: this application will exit when all remote stock
  227.         // watchers drop their references to the remote server
  228.         // object and unregister their interest in watching stock
  229.         // reports.
  230.  
  231.     } catch (Exception e) {
  232.         System.out.println("StockServer.main: an exception occurred: " +
  233.                    e.getMessage());
  234.         e.printStackTrace();
  235.     }
  236.     }
  237. }
  238.