src/share/classes/com/sun/jndi/ldap/NamingEventNotifier.java

Print this page




  33 
  34 import java.util.Vector;
  35 import com.sun.jndi.toolkit.ctx.Continuation;
  36 
  37 /**
  38   * Gathers information to generate events by using the Persistent Search
  39   * control.
  40   *<p>
  41   * This class maintains a list of listeners all interested in the same
  42   * "search" request. It creates a thread that does the persistent search
  43   * and blocks, collecting the results of the search.
  44   * For each result that it receives from the search, it fires the
  45   * corresponding event to its listeners. If an exception is encountered,
  46   * it fires a NamingExceptionEvent.
  47   *
  48   * @author Rosanna Lee
  49   */
  50 final class NamingEventNotifier implements Runnable {
  51     private final static boolean debug = false;
  52 
  53     private Vector namingListeners;
  54     private Thread worker;
  55     private LdapCtx context;
  56     private EventContext eventSrc;
  57     private EventSupport support;
  58     private NamingEnumeration results;
  59 
  60     // package private; used by EventSupport to remove it
  61     NotifierArgs info;
  62 
  63     NamingEventNotifier(EventSupport support, LdapCtx ctx, NotifierArgs info,
  64         NamingListener firstListener) throws NamingException {
  65         this.info = info;
  66         this.support = support;
  67 
  68         Control psearch;
  69         try {
  70             psearch = new PersistentSearchControl(
  71                 info.mask,
  72                 true /* no info about original entry(s) */,
  73                 true /* additional info about changes */,
  74                 Control.CRITICAL);
  75         } catch (java.io.IOException e) {
  76             NamingException ne = new NamingException(
  77                 "Problem creating persistent search control");
  78             ne.setRootCause(e);
  79             throw ne;
  80         }
  81 
  82         // Add psearch control to existing list
  83         context = (LdapCtx)ctx.newInstance(new Control[]{psearch});
  84         eventSrc = ctx;
  85 
  86         namingListeners = new Vector();
  87         namingListeners.addElement(firstListener);
  88 
  89         worker = Obj.helper.createThread(this);
  90         worker.setDaemon(true);  // not a user thread
  91         worker.start();
  92     }
  93 
  94     // package private; used by EventSupport; namingListener already synchronized
  95     void addNamingListener(NamingListener l) {
  96         namingListeners.addElement(l);
  97     }
  98 
  99     // package private; used by EventSupport; namingListener already synchronized
 100     void removeNamingListener(NamingListener l) {
 101         namingListeners.removeElement(l);
 102     }
 103 
 104     // package private; used by EventSupport; namingListener already synchronized
 105     boolean hasNamingListeners() {
 106         return namingListeners.size() > 0;
 107     }
 108 
 109     /**
 110      * Execute "persistent search".
 111      * For each result, create the appropriate NamingEvent and
 112      * queue to be dispatched to listeners.
 113      */
 114     public void run() {
 115         try {
 116             Continuation cont = new Continuation();
 117             cont.setError(this, info.name);
 118             Name nm = (info.name == null || info.name.equals("")) ?
 119                 new CompositeName() : new CompositeName().add(info.name);
 120 
 121             results = context.searchAux(nm, info.filter, info.controls,
 122                 true, false, cont);
 123 
 124             // Change root of search results so that it will generate
 125             // names relative to the event context instead of that
 126             // named by nm
 127             ((LdapSearchEnumeration)results).setStartName(context.currentParsedDN);

 128 
 129             SearchResult si;
 130             Control[] respctls;
 131             EntryChangeResponseControl ec;
 132             long changeNum;
 133 
 134             while (results.hasMore()) {
 135                 si = (SearchResult)results.next();
 136                 respctls = (si instanceof HasControls) ?
 137                     ((HasControls) si).getControls() : null;
 138 
 139                 if (debug) {
 140                     System.err.println("notifier: " + si);
 141                     System.err.println("respCtls: " + respctls);
 142                 }
 143 
 144                 // Just process ECs; ignore all the rest
 145                 if (respctls != null) {
 146                     for (int i = 0; i < respctls.length; i++) {
 147                         // %%% Should be checking OID instead of class
 148                         // %%% in case using someone else's  EC ctl
 149                         if (respctls[i] instanceof EntryChangeResponseControl) {
 150                             ec = (EntryChangeResponseControl)respctls[i];
 151                             changeNum = ec.getChangeNumber();
 152                             switch (ec.getChangeType()) {
 153                             case EntryChangeResponseControl.ADD:
 154                                 fireObjectAdded(si, changeNum);
 155                                 break;




  33 
  34 import java.util.Vector;
  35 import com.sun.jndi.toolkit.ctx.Continuation;
  36 
  37 /**
  38   * Gathers information to generate events by using the Persistent Search
  39   * control.
  40   *<p>
  41   * This class maintains a list of listeners all interested in the same
  42   * "search" request. It creates a thread that does the persistent search
  43   * and blocks, collecting the results of the search.
  44   * For each result that it receives from the search, it fires the
  45   * corresponding event to its listeners. If an exception is encountered,
  46   * it fires a NamingExceptionEvent.
  47   *
  48   * @author Rosanna Lee
  49   */
  50 final class NamingEventNotifier implements Runnable {
  51     private final static boolean debug = false;
  52 
  53     private Vector<NamingListener> namingListeners;
  54     private Thread worker;
  55     private LdapCtx context;
  56     private EventContext eventSrc;
  57     private EventSupport support;
  58     private NamingEnumeration<SearchResult> results;
  59 
  60     // package private; used by EventSupport to remove it
  61     NotifierArgs info;
  62 
  63     NamingEventNotifier(EventSupport support, LdapCtx ctx, NotifierArgs info,
  64         NamingListener firstListener) throws NamingException {
  65         this.info = info;
  66         this.support = support;
  67 
  68         Control psearch;
  69         try {
  70             psearch = new PersistentSearchControl(
  71                 info.mask,
  72                 true /* no info about original entry(s) */,
  73                 true /* additional info about changes */,
  74                 Control.CRITICAL);
  75         } catch (java.io.IOException e) {
  76             NamingException ne = new NamingException(
  77                 "Problem creating persistent search control");
  78             ne.setRootCause(e);
  79             throw ne;
  80         }
  81 
  82         // Add psearch control to existing list
  83         context = (LdapCtx)ctx.newInstance(new Control[]{psearch});
  84         eventSrc = ctx;
  85 
  86         namingListeners = new Vector<>();
  87         namingListeners.addElement(firstListener);
  88 
  89         worker = Obj.helper.createThread(this);
  90         worker.setDaemon(true);  // not a user thread
  91         worker.start();
  92     }
  93 
  94     // package private; used by EventSupport; namingListener already synchronized
  95     void addNamingListener(NamingListener l) {
  96         namingListeners.addElement(l);
  97     }
  98 
  99     // package private; used by EventSupport; namingListener already synchronized
 100     void removeNamingListener(NamingListener l) {
 101         namingListeners.removeElement(l);
 102     }
 103 
 104     // package private; used by EventSupport; namingListener already synchronized
 105     boolean hasNamingListeners() {
 106         return namingListeners.size() > 0;
 107     }
 108 
 109     /**
 110      * Execute "persistent search".
 111      * For each result, create the appropriate NamingEvent and
 112      * queue to be dispatched to listeners.
 113      */
 114     public void run() {
 115         try {
 116             Continuation cont = new Continuation();
 117             cont.setError(this, info.name);
 118             Name nm = (info.name == null || info.name.equals("")) ?
 119                 new CompositeName() : new CompositeName().add(info.name);
 120 
 121             results = context.searchAux(nm, info.filter, info.controls,
 122                 true, false, cont);
 123 
 124             // Change root of search results so that it will generate
 125             // names relative to the event context instead of that
 126             // named by nm
 127             ((LdapSearchEnumeration)(NamingEnumeration)results)
 128                     .setStartName(context.currentParsedDN);
 129 
 130             SearchResult si;
 131             Control[] respctls;
 132             EntryChangeResponseControl ec;
 133             long changeNum;
 134 
 135             while (results.hasMore()) {
 136                 si = results.next();
 137                 respctls = (si instanceof HasControls) ?
 138                     ((HasControls) si).getControls() : null;
 139 
 140                 if (debug) {
 141                     System.err.println("notifier: " + si);
 142                     System.err.println("respCtls: " + respctls);
 143                 }
 144 
 145                 // Just process ECs; ignore all the rest
 146                 if (respctls != null) {
 147                     for (int i = 0; i < respctls.length; i++) {
 148                         // %%% Should be checking OID instead of class
 149                         // %%% in case using someone else's  EC ctl
 150                         if (respctls[i] instanceof EntryChangeResponseControl) {
 151                             ec = (EntryChangeResponseControl)respctls[i];
 152                             changeNum = ec.getChangeNumber();
 153                             switch (ec.getChangeType()) {
 154                             case EntryChangeResponseControl.ADD:
 155                                 fireObjectAdded(si, changeNum);
 156                                 break;