PageRenderTime 59ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Events/PSearchEventSource.cs

https://github.com/iainlane/mono
C# | 280 lines | 187 code | 29 blank | 64 comment | 25 complexity | 1594b16d099fbbcd7b41f9710cdac320 MD5 | raw file
  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:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  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. *******************************************************************************/
  23. //
  24. // Novell.Directory.Ldap.Events.PSearchEventSource.cs
  25. //
  26. // Author:
  27. // Anil Bhatia (banil@novell.com)
  28. //
  29. // (C) 2003 Novell, Inc (http://www.novell.com)
  30. //
  31. using System;
  32. using Novell.Directory.Ldap.Controls;
  33. namespace Novell.Directory.Ldap.Events
  34. {
  35. /// <summary>
  36. /// This is the source class for Ldap events.
  37. /// </summary>
  38. public class PSearchEventSource : LdapEventSource
  39. {
  40. protected SearchResultEventHandler search_result_event;
  41. /// <summary>
  42. /// Caller has to register with this event in order to be notified of
  43. /// corresponding Ldap search result event.
  44. /// </summary>
  45. public event SearchResultEventHandler SearchResultEvent
  46. {
  47. add
  48. {
  49. search_result_event += value;
  50. ListenerAdded();
  51. }
  52. remove
  53. {
  54. search_result_event -= value;
  55. ListenerRemoved();
  56. }
  57. }
  58. protected SearchReferralEventHandler search_referral_event;
  59. /// <summary>
  60. /// Caller has to register with this event in order to be notified of
  61. /// corresponding Ldap search reference event.
  62. /// </summary>
  63. public event SearchReferralEventHandler SearchReferralEvent
  64. {
  65. add
  66. {
  67. search_referral_event += value;
  68. ListenerAdded();
  69. }
  70. remove
  71. {
  72. search_referral_event -= value;
  73. ListenerRemoved();
  74. }
  75. }
  76. /// <summary>
  77. /// SearchResultEventHandler is the delegate definition for SearchResultEvent.
  78. /// The client (listener) has to register using this delegate in order to
  79. /// get corresponding Ldap events.
  80. /// </summary>
  81. public delegate
  82. void SearchResultEventHandler(
  83. object source,
  84. SearchResultEventArgs objArgs
  85. );
  86. /// <summary>
  87. /// SearchReferralEventHandler is the delegate definition for SearchReferralEvent.
  88. /// The client (listener) has to register using this delegate in order to
  89. /// get corresponding Ldap events.
  90. /// </summary>
  91. public delegate
  92. void SearchReferralEventHandler(
  93. object source,
  94. SearchReferralEventArgs objArgs
  95. );
  96. protected override int GetListeners()
  97. {
  98. int nListeners = 0;
  99. if (null != search_result_event)
  100. nListeners = search_result_event.GetInvocationList().Length;
  101. if (null != search_referral_event)
  102. nListeners += search_referral_event.GetInvocationList().Length;
  103. return nListeners;
  104. }
  105. protected LdapConnection mConnection;
  106. protected string mSearchBase;
  107. protected int mScope;
  108. protected string[] mAttrs;
  109. protected string mFilter;
  110. protected bool mTypesOnly;
  111. protected LdapSearchConstraints mSearchConstraints;
  112. protected LdapEventType mEventChangeType;
  113. protected LdapSearchQueue mQueue;
  114. // Constructor
  115. public PSearchEventSource(
  116. LdapConnection conn,
  117. string searchBase,
  118. int scope,
  119. string filter,
  120. string[] attrs,
  121. bool typesOnly,
  122. LdapSearchConstraints constraints,
  123. LdapEventType eventchangetype,
  124. bool changeonly
  125. )
  126. {
  127. // validate the input arguments
  128. if ((conn == null)
  129. || (searchBase == null)
  130. || (filter == null)
  131. || (attrs == null))
  132. {
  133. throw new ArgumentException("Null argument specified");
  134. }
  135. mConnection = conn;
  136. mSearchBase = searchBase;
  137. mScope = scope;
  138. mFilter = filter;
  139. mAttrs = attrs;
  140. mTypesOnly = typesOnly;
  141. mEventChangeType = eventchangetype;
  142. // make things ready for starting a search operation
  143. if (constraints == null)
  144. {
  145. mSearchConstraints = new LdapSearchConstraints();
  146. }
  147. else
  148. {
  149. mSearchConstraints = constraints;
  150. }
  151. //Create the persistent search control
  152. LdapPersistSearchControl psCtrl =
  153. new LdapPersistSearchControl((int)eventchangetype,// any change
  154. changeonly, //only get changes
  155. true, //return entry change controls
  156. true); //control is critcal
  157. // add the persistent search control to the search constraints
  158. mSearchConstraints.setControls(psCtrl);
  159. } // end of Constructor
  160. protected override void StartSearchAndPolling()
  161. {
  162. // perform the search with no attributes returned
  163. mQueue =
  164. mConnection.Search(mSearchBase, // container to search
  165. mScope, // search container's subtree
  166. mFilter, // search filter, all objects
  167. mAttrs, // don't return attributes
  168. mTypesOnly, // return attrs and values or attrs only.
  169. null, // use default search queue
  170. mSearchConstraints); // use default search constraints
  171. int[] ids = mQueue.MessageIDs;
  172. if (ids.Length != 1)
  173. {
  174. throw new LdapException(
  175. null,
  176. LdapException.LOCAL_ERROR,
  177. "Unable to Obtain Message Id"
  178. );
  179. }
  180. StartEventPolling(mQueue, mConnection, ids[0]);
  181. }
  182. protected override void StopSearchAndPolling()
  183. {
  184. mConnection.Abandon(mQueue);
  185. StopEventPolling();
  186. }
  187. protected override bool NotifyEventListeners(LdapMessage sourceMessage,
  188. EventClassifiers aClassification,
  189. int nType)
  190. {
  191. bool bListenersNotified = false;
  192. if (null == sourceMessage)
  193. {
  194. return bListenersNotified;
  195. }
  196. switch (sourceMessage.Type)
  197. {
  198. case LdapMessage.SEARCH_RESULT_REFERENCE :
  199. if (null != search_referral_event)
  200. {
  201. search_referral_event(this,
  202. new SearchReferralEventArgs(
  203. sourceMessage,
  204. aClassification,
  205. (LdapEventType)nType)
  206. );
  207. bListenersNotified = true;
  208. }
  209. break;
  210. case LdapMessage.SEARCH_RESPONSE:
  211. if (null != search_result_event)
  212. {
  213. LdapEventType changeType = LdapEventType.TYPE_UNKNOWN;
  214. LdapControl[] controls = sourceMessage.Controls;
  215. foreach(LdapControl control in controls)
  216. {
  217. if (control is LdapEntryChangeControl)
  218. {
  219. changeType = (LdapEventType)(((LdapEntryChangeControl)control).ChangeType);
  220. // TODO: Why is this continue here..? (from Java code..)
  221. // TODO: Why are we interested only in the last changeType..?
  222. continue;
  223. }
  224. }
  225. // if no changeType then value is TYPE_UNKNOWN
  226. search_result_event(this,
  227. new SearchResultEventArgs(
  228. sourceMessage,
  229. aClassification,
  230. changeType)
  231. );
  232. bListenersNotified = true;
  233. }
  234. break;
  235. case LdapMessage.SEARCH_RESULT:
  236. // This is a generic LDAP Event
  237. // TODO: Why the type is ANY...? (java code)
  238. NotifyDirectoryListeners(new LdapEventArgs(sourceMessage,
  239. EventClassifiers.CLASSIFICATION_LDAP_PSEARCH,
  240. LdapEventType.LDAP_PSEARCH_ANY));
  241. bListenersNotified = true;
  242. break;
  243. default:
  244. // This seems to be some unknown event.
  245. // Let this be notified to generic DirectoryListeners in the base class...
  246. break;
  247. }
  248. return bListenersNotified;
  249. }
  250. } // end of class PSearchEventSource
  251. }