home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 July / Chip_1998-07_cd.bin / zkuste / JBuilder / BDK / Win / bdk_sep97.exe / _SETUP.1 / QuoteServerImpl.java < prev    next >
Encoding:
Java Source  |  1997-09-10  |  7.3 KB  |  287 lines

  1.  
  2. package sunw.demo.quote;
  3.  
  4. import java.util.Properties;
  5. import java.util.Hashtable;
  6. import java.util.Vector;
  7. import java.util.EventObject;
  8. import java.rmi.Naming;
  9. import java.rmi.RemoteException;
  10. import java.rmi.server.UnicastRemoteObject;
  11. import java.rmi.RMISecurityManager;
  12. import java.net.InetAddress;
  13. import java.net.UnknownHostException;
  14.  
  15.  
  16. /** 
  17.  * The QuoteServer implementation.  The QuoteServer object
  18.  * starts a thread that polls a quote source and delivers 
  19.  * QuoteEvents to QuoteListeners.
  20.  * <p>
  21.  * Stock information can be collected from one of two sources: "Local" 
  22.  * or "Yahoo".  The latter is a real (delayed) data feed that reports
  23.  * quotes in a format that can be easily parsed.  The "Local" quote 
  24.  * source is just a random number generator.  The advantage of 
  25.  * the local source is that it can produce quotes quickly, this
  26.  * can make demos more interesting.
  27.  */
  28.  
  29. public class QuoteServerImpl 
  30.   extends UnicastRemoteObject 
  31.   implements QuoteServer
  32. {
  33.   private int quoteEventRate = 2;
  34.   private Thread quoteThread = null;
  35.   private String quoteSource = "Local";
  36.   private boolean quoteThreadStopped = false;
  37.   private Vector quoteListeners = new Vector();
  38.  
  39.  
  40.   /** 
  41.    * Construct a QuoteServer implementation and start its polling thread.
  42.    */
  43.   QuoteServerImpl() throws RemoteException
  44.   {
  45.     super();
  46.     quoteThread = new QuoteThread(this);
  47.     quoteThread.start();
  48.   }
  49.  
  50.  
  51.   /** 
  52.    * Get quotes for every stock symbol some QuoteListener is interested 
  53.    * in and then apply each listeners QuoteListener.quoteChanged()
  54.    * method to a new QuoteEvent object.
  55.    * <p>
  56.    * This method is not synchronized, notifying observers can
  57.    * take a while.
  58.    */
  59.  
  60.   void deliverQuotes()
  61.   {
  62.     /* Make a local (frozen) copy of the list of the current list of 
  63.      * QuoteListeners.  If there are no listeners, we're done
  64.      */
  65.  
  66.     Vector l;
  67.     int n;
  68.  
  69.     synchronized (this)
  70.     {
  71.       l = (Vector)quoteListeners.clone();
  72.       n = l.size();
  73.       if (n == 0) return;
  74.     }
  75.  
  76.     /* Make a list of the unique stock symbols that quoteListeners are 
  77.      * interested in.
  78.      */
  79.  
  80.     Vector symbols = new Vector();
  81.     for(int i = 0; i < l.size(); i++) {
  82.       QuoteListener quoteListener = (QuoteListener)l.elementAt(i);
  83.       try {
  84.     String s = quoteListener.getStockSymbol();
  85.     if ((s != null) && !(symbols.contains(s)))
  86.       symbols.addElement(s);
  87.       }
  88.       catch (RemoteException e) {
  89.       }
  90.     }
  91.     
  92.     /* Get quotes from quoteSource for each symbol and then deliver
  93.      * the QuoteEvents to the QuoteListeners that want them.
  94.      */
  95.  
  96.     Hashtable eventTable; 
  97.  
  98.     if (quoteSource.equalsIgnoreCase("Yahoo"))
  99.       eventTable = YahooQuote.getQuotes(this, symbols);
  100.     else 
  101.       eventTable = LocalQuote.getQuotes(this, symbols);
  102.  
  103.     if (eventTable == null)
  104.       return;
  105.  
  106.     QuoteListener quoteListener = null;
  107.  
  108.     for(int i = 0; i < l.size(); i++) {
  109.       try {
  110.     quoteListener = (QuoteListener)l.elementAt(i);
  111.     String symbol = quoteListener.getStockSymbol();
  112.     QuoteEvent e = (QuoteEvent)eventTable.get(symbol.toUpperCase());
  113.     quoteListener.quoteChanged(e);
  114.       }
  115.       catch (RemoteException e) {
  116.     // e.printStackTrace();
  117.     System.err.println("disconnecting listener " + quoteListener);
  118.     quoteListeners.removeElement(quoteListener);
  119.       }
  120.     }
  121.   }
  122.  
  123.  
  124.   /** 
  125.    * @return the quote source polling rate in seconds
  126.    */
  127.   public int getQuoteEventRate()
  128.   {
  129.     return quoteEventRate;
  130.   }
  131.  
  132.   /** 
  133.    * Sets the quote source polling rate.
  134.    * @param x the polling rate in seconds
  135.    */
  136.  
  137.   public void setQuoteEventRate(int x)
  138.   {
  139.     quoteEventRate = x;
  140.   }
  141.  
  142.  
  143.   /**
  144.    * The specified QuoteListeners <b>quoteChanged</b> method will 
  145.    * be called each time new quote data is available.  The QuoteListener
  146.    * object is added to a list of QuoteListeners managed by 
  147.    * this server, it can be removed with removeQuoteListener.
  148.    * 
  149.    * @see #removeQuoteListener
  150.    * @param l the QuoteListener
  151.    */      
  152.   public synchronized void addQuoteListener(QuoteListener x) throws RemoteException
  153.   {
  154.     quoteListeners.addElement(x);
  155.   }
  156.  
  157.   /** 
  158.    * Remove this QuoteListener from the servers internal list.  If the
  159.    * QuoteListener isn't on the list, silently do nothing.
  160.    * 
  161.    * @see #addQuoteListener
  162.    * @param l the QuoteListener
  163.    */      
  164.   public synchronized void removeQuoteListener(QuoteListener x) throws RemoteException
  165.   {
  166.     quoteListeners.removeElement(x);
  167.   }
  168.  
  169.  
  170.   /** 
  171.    * The HTTP proxy host and port number are stored in the System
  172.    * property list under "http.proxyHost" and "http.proxyPort".
  173.    * We just combine the two values into a single object here.
  174.    * @return the HTTP proxy host and port number for this server
  175.    * 
  176.    * @see #setHttpProxy
  177.    */      
  178.   public HttpProxy getHttpProxy() throws RemoteException
  179.   {
  180.     Properties systemProps = System.getProperties();
  181.     String host = systemProps.getProperty("http.proxyHost");
  182.     String portString = systemProps.getProperty("http.proxyPort");
  183.     try {
  184.       int port = Integer.parseInt(portString, 10);
  185.       return new HttpProxy(host, port);
  186.     }
  187.     catch (NumberFormatException e) {
  188.       throw new RemoteException("can't parse port number", e);
  189.     }
  190.   }
  191.  
  192.   /** 
  193.    * If the specified host is valid and the port number is 
  194.    * positive then set the System properties: "http.proxyHost" 
  195.    * and "http.proxyPort".  Otherwise throw a RemoteException.
  196.    * The HTTP proxy values only matter if the quote source is 
  197.    * "Yahoo", i.e. if we're going to the internet for data.
  198.    * 
  199.    * @param x the new values for host and port
  200.    * @see #getHttpProxy
  201.    */      
  202.   public void setHttpProxy(HttpProxy x) throws RemoteException
  203.   {
  204.     String host = x.getHost();
  205.     int port = x.getPort();
  206.  
  207.     if (port < 0)
  208.       throw new RemoteException("invalid port number");
  209.  
  210.     InetAddress addr = null;
  211.     try {
  212.       addr = InetAddress.getByName(host);
  213.     } 
  214.     catch (UnknownHostException e) {
  215.       throw new RemoteException("not a valid host", e);
  216.     }
  217.  
  218.     Properties systemProps = System.getProperties();
  219.     systemProps.put("http.proxyHost", host);
  220.     systemProps.put("http.proxyPort", String.valueOf(port));
  221.   }
  222.  
  223.  
  224.   /**
  225.    * @return a string that represents the source for quote data
  226.    * @see #setQuoteSource
  227.    */
  228.   public String getQuoteSource() throws RemoteException
  229.   {
  230.     return quoteSource;
  231.   }
  232.  
  233.   /**
  234.    * Specify where quote data will come from.  If quoteSource is "Local"
  235.    * then the sunw.demo.LocalQuote is used, it generates moderately
  236.    * random data.  If quoteSource is "Yahoo" then the sunw.demo.YahooQuote
  237.    * class is used, it collects quote data from the YahooQuote web site.
  238.    * 
  239.    * @param x must be "Yahoo" or "Local"
  240.    * @see #getQuoteSource
  241.    */
  242.   public void setQuoteSource(String x) throws RemoteException
  243.   {
  244.     quoteSource = x;
  245.   }
  246.  
  247.  
  248.   boolean isQuoteThreadStopped()
  249.   {
  250.     return quoteThreadStopped;
  251.   }
  252.  
  253.  
  254.   void stopQuoteThread()
  255.   {
  256.     quoteThreadStopped = true;
  257.   }
  258. }
  259.  
  260.  
  261.  
  262. class QuoteThread extends Thread
  263. {
  264.   private QuoteServerImpl quoteServerImpl;
  265.  
  266.   QuoteThread(QuoteServerImpl x)
  267.   {
  268.     super();
  269.     quoteServerImpl = x;
  270.   }
  271.  
  272.   public void run()
  273.   {
  274.     try {
  275.       while(!quoteServerImpl.isQuoteThreadStopped()){
  276.     // TBD - get time here
  277.     quoteServerImpl.deliverQuotes();
  278.     // TBD sleep remaining time here
  279.     sleep(quoteServerImpl.getQuoteEventRate() * 1000);
  280.       }
  281.     }
  282.     catch (InterruptedException e) {
  283.       quoteServerImpl.stopQuoteThread();
  284.     }
  285.   }
  286. }
  287.