home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / VCafe / prosrc.bin / AsyncNotifier.java < prev    next >
Encoding:
Java Source  |  1998-03-18  |  6.4 KB  |  200 lines

  1. /*
  2.  * Copyright (c) 1997 Krumel & Associates, Inc. All Rights Reserved.
  3.  *
  4.  * www.krumel.com - controls@krumel.com
  5.  *
  6.  * Permission is given to the buyer of this package for one software
  7.  * developer to use this software on one CPU (one workstation) and to make
  8.  * one backup copy.  You may uitilize and/or modify this class for use in your
  9.  * projects.  You may distribute or sell any executable which results from
  10.  * using this code in yur application, except a utility or class of similar
  11.  * nature to this product.  You may distribute this product in compiled
  12.  * form only, but soley to be used with your cmpiled executable product
  13.  * for the puposes of dynamic loading. You may NOT redistribute the source
  14.  * code in any form or make it accessible through a network or other
  15.  * distribution media to others. Please refer to the file "copyright.html"
  16.  * for further important copyright and licensing information.
  17.  *
  18.  * The source code is the confidential and proprietary information
  19.  * of Krumel & Associates, Inc. ("Confidential Information").  You shall
  20.  * not disclose such Confidential Information and shall use it only in
  21.  * accordance with the terms of the license agreement you entered into
  22.  * with Krumel & Associates, Inc..
  23.  
  24.  * KRUMEL & ASSOCIATES MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
  25.  * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
  26.  * NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  27.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. KRUMEL & ASSOCIATES SHALL NOT
  28.  * BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
  29.  * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  30.  */
  31.  
  32. package symantec.itools.db.awt.genutil;
  33.  
  34. import java.util.*;
  35.  
  36. /**
  37.  * Class encapsulates a callback to an object.
  38.  */
  39. class NotifyPackage {
  40.     Notifiable      target;
  41.     Vector          args = new Vector();
  42.  
  43.     NotifyPackage(Notifiable n) {
  44.         this(n, null);
  45.     }
  46.  
  47.     NotifyPackage(Notifiable n, Object o) {
  48.         target = n;
  49.         addArg(o);
  50.     }
  51.  
  52.     final void addArg(Object arg) {
  53.         args.addElement(arg);
  54.     }
  55.  
  56.     final void asyncNotify() {
  57.         //catch all exceptions so don't end thread
  58.         try {
  59.             if( target!=null){
  60.                 for(int i=0;i<args.size();i++)
  61.                 {
  62.                     if(args.elementAt(i)==null)
  63.                     {
  64.                          args.removeAllElements();
  65.                         /*<vj>*/
  66.                          //return;
  67.                          break;
  68.                         /*<vj>*/
  69.  
  70.                     }
  71.                 }
  72.             target.asyncNotify(args);
  73.             }
  74.         } catch(Exception ex) {
  75.             System.err.println("Error occurred during asynchronous notification");
  76.             ex.printStackTrace();
  77.         }
  78.         args.removeAllElements();
  79.  
  80.  
  81.     }
  82. }
  83.  
  84. /**
  85.  * Class provides the ability for classes to implement asynchronously executed
  86.  * methods.  Classes usually create their own thread to perform asynchronous
  87.  * code, but the problem of proliferating the number of threads active within
  88.  * a virtual machine.  The more threads present, the more overhead and less
  89.  * efficiently it runs.
  90.  * <p>
  91.  * This class could be used to perform offscreen drawing in a separate thread,
  92.  * simulate user events, or perform background tasks.  Note: Only one thread
  93.  * is created for the entire virtual machine so blocking calls should not
  94.  * be performed within the context of the callback thread, for this would
  95.  * block all other objects from getting notified.
  96.  * <p>
  97.  * Objects to be called back must implement the Notifiable interface.
  98.  */
  99. public class AsyncNotifier extends Thread {
  100.     /**
  101.      * The objects that need to be notified.
  102.      */
  103.     Hashtable      toBeNotified = new Hashtable();
  104.  
  105.     /**
  106.      * The actual notifier within a virtual machine.
  107.      */
  108.     private static AsyncNotifier notifier = new AsyncNotifier();
  109.  
  110.     /**
  111.      * Private contructor used to construct the one and only notifier.
  112.      */
  113.     private AsyncNotifier() {
  114.         setPriority(6);
  115.         start();
  116.     }
  117.  
  118.     /**
  119.      * Class method used to request an asynchronous callback to an object.
  120.      * @param n The object to be notfied.
  121.      */
  122.     public static void notify(Notifiable n) {
  123.         notifier.notifyObject(n, null);
  124.     }
  125.  
  126.     /**
  127.      * Class method used to request an asynchronous callback to an object.
  128.      * When the object is notified, a context argument is passed to it.
  129.      * @param n The object to be notfied.
  130.      * @param arg The context argument (object/class specific).
  131.      *
  132.      */
  133.     public static void notify(Notifiable n, Object arg) {
  134.         notifier.notifyObject(n, arg);
  135.     }
  136.  
  137.     /**
  138.      * The internal function used to actually register the object for a callback.
  139.      */
  140.     private final void notifyObject(Notifiable n) {
  141.         notifyObject(n, null);
  142.     }
  143.  
  144.     /**
  145.      * The internal function used to actually register the object for a callback
  146.      * using a context argument.
  147.      */
  148.     private final synchronized void notifyObject(Notifiable n, Object arg) {
  149.         NotifyPackage p;
  150.         p = (NotifyPackage)toBeNotified.get(n);
  151.         if (p == null) {
  152.             p = new NotifyPackage(n, arg);
  153.             toBeNotified.put(n, p);
  154.         }
  155.  
  156.         p.addArg(arg);
  157.         notify();
  158.     }
  159.  
  160.     /**
  161.      * The notifiers body.
  162.      */
  163.     public void run() {
  164.         while(true) {
  165.                 doNotifications();
  166.             try {
  167.                 synchronized(this) {
  168.                     if (toBeNotified.size() == 0) {
  169.                         wait();
  170.                     } else {
  171.                         //yeild to let other threads run
  172.                         Thread.sleep(0);
  173.                     }
  174.                 }
  175.             } catch(Exception ex) {}
  176.         }
  177.     }
  178.  
  179.     /**
  180.      * Method iterates the objects to be notified and triggers the callbacks.
  181.      */
  182.     private void doNotifications() {
  183.         Hashtable ht;
  184.         synchronized (this) {
  185.             ht = (Hashtable)toBeNotified.clone();
  186.             toBeNotified.clear();
  187.         }
  188.  
  189.         Enumeration e = ht.elements();
  190.         NotifyPackage p;
  191.  
  192.         while (e.hasMoreElements()) {
  193.             p = (NotifyPackage)e.nextElement();
  194.             toBeNotified.remove(p.target);
  195.             p.asyncNotify();
  196.         }
  197.     }
  198. }
  199.  
  200.