2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / Novell.Directory.Ldap / Novell.Directory.Ldap.Events / PSearchEventSource.cs
blobcc8dfa748a81531eabe8295db20c3fb77c079039
1 /******************************************************************************
2 * The MIT License
3 * Copyright (c) 2003 Novell Inc. www.novell.com
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the Software), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *******************************************************************************/
24 // Novell.Directory.Ldap.Events.PSearchEventSource.cs
26 // Author:
27 // Anil Bhatia (banil@novell.com)
29 // (C) 2003 Novell, Inc (http://www.novell.com)
33 using System;
34 using Novell.Directory.Ldap.Controls;
36 namespace Novell.Directory.Ldap.Events
38 /// <summary>
39 /// This is the source class for Ldap events.
40 /// </summary>
41 public class PSearchEventSource : LdapEventSource
43 protected SearchResultEventHandler search_result_event;
45 /// <summary>
46 /// Caller has to register with this event in order to be notified of
47 /// corresponding Ldap search result event.
48 /// </summary>
49 public event SearchResultEventHandler SearchResultEvent
51 add
53 search_result_event += value;
54 ListenerAdded();
56 remove
58 search_result_event -= value;
59 ListenerRemoved();
63 protected SearchReferralEventHandler search_referral_event;
65 /// <summary>
66 /// Caller has to register with this event in order to be notified of
67 /// corresponding Ldap search reference event.
68 /// </summary>
69 public event SearchReferralEventHandler SearchReferralEvent
71 add
73 search_referral_event += value;
74 ListenerAdded();
76 remove
78 search_referral_event -= value;
79 ListenerRemoved();
83 /// <summary>
84 /// SearchResultEventHandler is the delegate definition for SearchResultEvent.
85 /// The client (listener) has to register using this delegate in order to
86 /// get corresponding Ldap events.
87 /// </summary>
88 public delegate
89 void SearchResultEventHandler(
90 object source,
91 SearchResultEventArgs objArgs
94 /// <summary>
95 /// SearchReferralEventHandler is the delegate definition for SearchReferralEvent.
96 /// The client (listener) has to register using this delegate in order to
97 /// get corresponding Ldap events.
98 /// </summary>
99 public delegate
100 void SearchReferralEventHandler(
101 object source,
102 SearchReferralEventArgs objArgs
105 protected override int GetListeners()
107 int nListeners = 0;
108 if (null != search_result_event)
109 nListeners = search_result_event.GetInvocationList().Length;
111 if (null != search_referral_event)
112 nListeners += search_referral_event.GetInvocationList().Length;
114 return nListeners;
117 protected LdapConnection mConnection;
118 protected string mSearchBase;
119 protected int mScope;
120 protected string[] mAttrs;
121 protected string mFilter;
122 protected bool mTypesOnly;
123 protected LdapSearchConstraints mSearchConstraints;
124 protected LdapEventType mEventChangeType;
126 protected LdapSearchQueue mQueue;
128 // Constructor
129 public PSearchEventSource(
130 LdapConnection conn,
131 string searchBase,
132 int scope,
133 string filter,
134 string[] attrs,
135 bool typesOnly,
136 LdapSearchConstraints constraints,
137 LdapEventType eventchangetype,
138 bool changeonly
141 // validate the input arguments
142 if ((conn == null)
143 || (searchBase == null)
144 || (filter == null)
145 || (attrs == null))
147 throw new ArgumentException("Null argument specified");
150 mConnection = conn;
151 mSearchBase = searchBase;
152 mScope = scope;
153 mFilter = filter;
154 mAttrs = attrs;
155 mTypesOnly = typesOnly;
156 mEventChangeType = eventchangetype;
158 // make things ready for starting a search operation
159 if (constraints == null)
161 mSearchConstraints = new LdapSearchConstraints();
163 else
165 mSearchConstraints = constraints;
168 //Create the persistent search control
169 LdapPersistSearchControl psCtrl =
170 new LdapPersistSearchControl((int)eventchangetype,// any change
171 changeonly, //only get changes
172 true, //return entry change controls
173 true); //control is critcal
175 // add the persistent search control to the search constraints
176 mSearchConstraints.setControls(psCtrl);
177 } // end of Constructor
179 protected override void StartSearchAndPolling()
181 // perform the search with no attributes returned
182 mQueue =
183 mConnection.Search(mSearchBase, // container to search
184 mScope, // search container's subtree
185 mFilter, // search filter, all objects
186 mAttrs, // don't return attributes
187 mTypesOnly, // return attrs and values or attrs only.
188 null, // use default search queue
189 mSearchConstraints); // use default search constraints
191 int[] ids = mQueue.MessageIDs;
193 if (ids.Length != 1)
195 throw new LdapException(
196 null,
197 LdapException.LOCAL_ERROR,
198 "Unable to Obtain Message Id"
202 StartEventPolling(mQueue, mConnection, ids[0]);
205 protected override void StopSearchAndPolling()
207 mConnection.Abandon(mQueue);
208 StopEventPolling();
211 protected override bool NotifyEventListeners(LdapMessage sourceMessage,
212 EventClassifiers aClassification,
213 int nType)
215 bool bListenersNotified = false;
216 if (null == sourceMessage)
218 return bListenersNotified;
221 switch (sourceMessage.Type)
223 case LdapMessage.SEARCH_RESULT_REFERENCE :
224 if (null != search_referral_event)
226 search_referral_event(this,
227 new SearchReferralEventArgs(
228 sourceMessage,
229 aClassification,
230 (LdapEventType)nType)
232 bListenersNotified = true;
234 break;
236 case LdapMessage.SEARCH_RESPONSE:
237 if (null != search_result_event)
239 LdapEventType changeType = LdapEventType.TYPE_UNKNOWN;
240 LdapControl[] controls = sourceMessage.Controls;
241 foreach(LdapControl control in controls)
243 if (control is LdapEntryChangeControl)
245 changeType = (LdapEventType)(((LdapEntryChangeControl)control).ChangeType);
246 // TODO: Why is this continue here..? (from Java code..)
247 // TODO: Why are we interested only in the last changeType..?
248 continue;
251 // if no changeType then value is TYPE_UNKNOWN
252 search_result_event(this,
253 new SearchResultEventArgs(
254 sourceMessage,
255 aClassification,
256 changeType)
258 bListenersNotified = true;
260 break;
262 case LdapMessage.SEARCH_RESULT:
263 // This is a generic LDAP Event
264 // TODO: Why the type is ANY...? (java code)
265 NotifyDirectoryListeners(new LdapEventArgs(sourceMessage,
266 EventClassifiers.CLASSIFICATION_LDAP_PSEARCH,
267 LdapEventType.LDAP_PSEARCH_ANY));
268 bListenersNotified = true;
269 break;
271 default:
272 // This seems to be some unknown event.
273 // Let this be notified to generic DirectoryListeners in the base class...
274 break;
277 return bListenersNotified;
279 } // end of class PSearchEventSource