Fixes for TARGET_JVM secure binding.
[mono.git] / mcs / class / Novell.Directory.Ldap / Novell.Directory.Ldap.Controls / LdapVirtualListControl.cs
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.Controls.LdapVirtualListControl.cs
25 //
26 // Author:
27 //   Sunil Kumar (Sunilk@novell.com)
28 //
29 // (C) 2003 Novell, Inc (http://www.novell.com)
30 //
31
32 using System;
33 using Novell.Directory.Ldap;
34 using Novell.Directory.Ldap.Asn1;
35
36 namespace Novell.Directory.Ldap.Controls
37 {
38         
39         /* The following is the ASN.1 of the VLV Request packet:
40         *
41         * VirtualListViewRequest ::= SEQUENCE {
42         *      beforeCount    INTEGER (0..maxInt),
43         *         afterCount     INTEGER (0..maxInt),
44         *      CHOICE {
45         *          byoffset [0] SEQUENCE {
46         *              offset          INTEGER (0 .. maxInt),
47         *              contentCount    INTEGER (0 .. maxInt) },
48         *          greaterThanOrEqual [1] AssertionValue },
49         *      contextID     OCTET STRING OPTIONAL }
50         *
51         */
52         
53         /// <summary> LdapVirtualListControl is a Server Control used to specify
54         /// that results from a search are to be returned in pages - which are
55         /// subsets of the entire virtual result set.
56         /// 
57         /// On success, an updated LdapVirtualListResponse object is
58         /// returned as a response Control, containing information on the virtual
59         /// list size and the actual first index. This object can then be used
60         /// by the client with a new requested position or length and sent to the
61         /// server to obtain a different segment of the virtual list.
62         /// 
63         /// </summary>
64         public class LdapVirtualListControl:LdapControl
65         {
66                 /// <summary>    Returns the number of entries after the top/center one to return per
67                 /// page of results.
68                 /// </summary>
69                 virtual public int AfterCount
70                 {
71                         get
72                         {
73                                 return m_afterCount;
74                         }
75                         
76                 }
77                 /// <summary>    Returns the number of entries before the top/center one to return per
78                 /// page of results.
79                 /// </summary>
80                 virtual public int BeforeCount
81                 {
82                         get
83                         {
84                                 return m_beforeCount;
85                         }
86                         
87                 }
88                 /// <summary>    Returns the size of the virtual search results list. For a newly
89                 /// constructed control - one which is not the result of parseResponse on
90                 /// a control returned by a server - the method returns -1.
91                 /// </summary>
92                 /// <summary>    Sets the assumed size of the virtual search results list. This will
93                 /// typically be a number returned on a previous virtual list request in
94                 /// an LdapVirtualListResponse.
95                 /// </summary>
96                 virtual public int ListSize
97                 {
98                         get
99                         {
100                                 return m_contentCount;
101                         }
102                         
103                         set
104                         {
105                                 m_contentCount = value;
106                                 
107                                 /* since we just changed a field we need to rebuild the ber
108                                 * encoded control
109                                 */
110                                 BuildIndexedVLVRequest();
111                                 
112                                 /* Set the request data field in the in the parent LdapControl to
113                                 * the ASN.1 encoded value of this control.  This encoding will be
114                                 * appended to the search request when the control is sent.
115                                 */
116                                 setValue(m_vlvRequest.getEncoding(new LBEREncoder()));
117                         }
118                         
119                 }
120                 /// <summary>   Returns the cookie used by some servers to optimize the processing of
121                 /// virtual list requests.
122                 /// </summary>
123                 /// <summary>    Sets the cookie used by some servers to optimize the processing of
124                 /// virtual list requests. It should be the context field returned in a
125                 /// virtual list response control for the same search.
126                 /// </summary>
127                 virtual public System.String Context
128                 {
129                         get
130                         {
131                                 return m_context;
132                         }
133                         
134                         set
135                         {
136                                 /* Index of the context field if one exists in the ber
137                                 */
138                                 int CONTEXTIDINDEX = 3;
139                                 
140                                 /* Save off the new value in private variable
141                                 */
142                                 m_context = value;
143                                 
144                                 /* Is there a context field that is already in the ber
145                                 */
146                                 if (m_vlvRequest.size() == 4)
147                                 {
148                                         /* If YES then replace it */
149                                         m_vlvRequest.set_Renamed(CONTEXTIDINDEX, new Asn1OctetString(m_context));
150                                 }
151                                 else if (m_vlvRequest.size() == 3)
152                                 {
153                                         /* If no then add a new one */
154                                         m_vlvRequest.add(new Asn1OctetString(m_context));
155                                 }
156                                 
157                                 /* Set the request data field in the in the parent LdapControl to
158                                 * the ASN.1 encoded value of this control.  This encoding will be
159                                 * appended to the search request when the control is sent.
160                                 */
161                                 setValue(m_vlvRequest.getEncoding(new LBEREncoder()));
162                         }
163                         
164                 }
165                 
166                 /* The ASN.1 for the VLV Request has CHOICE field. These private
167                 * variables represent differnt ids for these different options
168                 */
169                 private static int BYOFFSET = 0;
170                 private static int GREATERTHANOREQUAL = 1;
171                 
172                 
173                 /// <summary> The Request OID for a VLV Request</summary>
174                 private static System.String requestOID = "2.16.840.1.113730.3.4.9";
175                 
176                 /*
177                 * The Response stOID for a VLV Response
178                 */
179                 private static System.String responseOID = "2.16.840.1.113730.3.4.10";
180                 
181                 /*
182                 * The encoded ASN.1 VLV Control is stored in this variable
183                 */
184                 private Asn1Sequence m_vlvRequest;
185                 
186                 
187                 /* Private instance variables go here.
188                 * These variables are used to store copies of various fields
189                 * that can be set in a VLV control. One could have managed
190                 * without really defining these private variables by reverse
191                 * engineering each field from the ASN.1 encoded control.
192                 * However that would have complicated and slowed down the code.
193                 */
194                 private int m_beforeCount;
195                 private int m_afterCount;
196                 private System.String m_jumpTo;
197                 private System.String m_context = null;
198                 private int m_startIndex = 0;
199                 private int m_contentCount = - 1;
200                 
201                 /// <summary> Constructs a virtual list control using the specified filter
202                 /// expression.
203                 /// 
204                 /// The expression specifies the first entry to be used for the
205                 /// virtual search results. The other two paramers are the number of
206                 /// entries before and after a located index to be returned.
207                 /// 
208                 /// </summary>
209                 /// <param name="jumpTo">           A search expression that defines the first
210                 /// element to be returned in the virtual search results. The filter
211                 /// expression in the search operation itself may be, for example,
212                 /// "objectclass=person" and the jumpTo expression in the virtual
213                 /// list control may be "cn=m*", to retrieve a subset of entries
214                 /// starting at or centered around those with a common name beginning
215                 /// with the letter "M". 
216                 /// 
217                 /// </param>
218                 /// <param name="beforeCount">   The number of entries before startIndex (the
219                 /// reference entry) to be returned. 
220                 /// 
221                 /// </param>
222                 /// <param name="afterCount">       The number of entries after startIndex to be
223                 /// returned. 
224                 /// </param>
225                 public LdapVirtualListControl(System.String jumpTo, int beforeCount, int afterCount):this(jumpTo, beforeCount, afterCount, null)
226                 {
227                         return ;
228                 }
229                 
230                 
231                 
232                 /// <summary> Constructs a virtual list control using the specified filter
233                 /// expression along with an optional server context.
234                 /// 
235                 /// The expression specifies the first entry to be used for the
236                 /// virtual search results. The other two paramers are the number of
237                 /// entries before and after a located index to be returned.
238                 /// 
239                 /// </summary>
240                 /// <param name="jumpTo">   A search expression that defines the first
241                 /// element to be returned in the virtual search results. The filter
242                 /// expression in the search operation itself may be, for example,
243                 /// "objectclass=person" and the jumpTo expression in the virtual
244                 /// list control may be "cn=m*", to retrieve a subset of entries
245                 /// starting at or centered around those with a common name beginning
246                 /// with the letter "M".
247                 /// 
248                 /// </param>
249                 /// <param name="beforeCount">The number of entries before startIndex (the
250                 /// reference entry) to be returned. 
251                 /// 
252                 /// </param>
253                 /// <param name="afterCount">The number of entries after startIndex to be
254                 /// returned. 
255                 /// 
256                 /// </param>
257                 /// <param name="context">Used by some implementations to process requests
258                 /// more efficiently. The context should be null on the first search,
259                 /// and thereafter it should be whatever was returned by the server in the
260                 /// virtual list response control.
261                 /// </param>
262                 public LdapVirtualListControl(System.String jumpTo, int beforeCount, int afterCount, System.String context):base(requestOID, true, null)
263                 {
264                         
265                         /* Save off the fields in local variables
266                         */
267                         m_beforeCount = beforeCount;
268                         m_afterCount = afterCount;
269                         m_jumpTo = jumpTo;
270                         m_context = context;
271                         
272                         /* Call private method to build the ASN.1 encoded request packet.
273                         */
274                         BuildTypedVLVRequest();
275                         
276                         /* Set the request data field in the in the parent LdapControl to
277                         * the ASN.1 encoded value of this control.  This encoding will be
278                         * appended to the search request when the control is sent.
279                         */
280                         setValue(m_vlvRequest.getEncoding(new LBEREncoder()));
281                         return ;
282                 }
283                 
284                 /// <summary>Private method used to construct the ber encoded control
285                 /// Used only when using the typed mode of VLV Control.
286                 /// </summary>
287                 private void  BuildTypedVLVRequest()
288                 {
289                         /* Create a new Asn1Sequence object */
290                         m_vlvRequest = new Asn1Sequence(4);
291                         
292                         /* Add the beforeCount and afterCount fields to the sequence */
293                         m_vlvRequest.add(new Asn1Integer(m_beforeCount));
294                         m_vlvRequest.add(new Asn1Integer(m_afterCount));
295                         
296                         /* The next field is dependent on the type of indexing being used.
297                         * A "typed" VLV request uses a ASN.1 OCTET STRING to index to the
298                         * correct object in the list.  Encode the ASN.1 CHOICE corresponding
299                         * to this option (as indicated by the greaterthanOrEqual field)
300                         * in the ASN.1.
301                         */
302                         m_vlvRequest.add(new Asn1Tagged(new Asn1Identifier(Asn1Identifier.CONTEXT, false, GREATERTHANOREQUAL), new Asn1OctetString(m_jumpTo), false));
303                         
304                         /* Add the optional context string if one is available.
305                         */
306                         if ((System.Object) m_context != null)
307                                 m_vlvRequest.add(new Asn1OctetString(m_context));
308                         
309                         return ;
310                 }
311                 
312                 /// <summary> Use this constructor to fetch a subset when the size of the
313                 /// virtual list is known,
314                 /// 
315                 /// 
316                 /// </summary>
317                 /// <param name="beforeCount">The number of entries before startIndex (the
318                 /// reference entry) to be returned. 
319                 /// 
320                 /// </param>
321                 /// <param name="afterCount">   The number of entries after startIndex to be
322                 /// returned.
323                 /// 
324                 /// </param>
325                 /// <param name="startIndex">The index of the reference entry to be returned.
326                 /// 
327                 /// </param>
328                 /// <param name="contentCount">The total number of entries assumed to be in the
329                 /// list. This is a number returned on a previous search, in the
330                 /// LdapVirtualListResponse. The server may use this number to adjust
331                 /// the returned subset offset.
332                 /// </param>
333                 public LdapVirtualListControl(int startIndex, int beforeCount, int afterCount, int contentCount):this(startIndex, beforeCount, afterCount, contentCount, null)
334                 {
335                         return ;
336                 }
337                 
338                 
339                 
340                 /// <summary> Use this constructor to fetch a subset when the size of the
341                 /// virtual list is known,
342                 /// 
343                 /// 
344                 /// </summary>
345                 /// <param name="beforeCount">   The number of entries before startIndex (the
346                 /// reference entry) to be returned.
347                 /// 
348                 /// </param>
349                 /// <param name="afterCount">       The number of entries after startIndex to be
350                 /// returned.
351                 /// 
352                 /// </param>
353                 /// <param name="startIndex">    The index of the reference entry to be
354                 /// returned.
355                 /// 
356                 /// </param>
357                 /// <param name="contentCount">   The total number of entries assumed to be in the
358                 /// list. This is a number returned on a previous search, in the
359                 /// LdapVirtualListResponse. The server may use this number to adjust
360                 /// the returned subset offset.
361                 /// 
362                 /// </param>
363                 /// <param name="context">       Used by some implementations to process requests
364                 /// more efficiently. The context should be null on the first search,
365                 /// and thereafter it should be whatever was returned by the server in the
366                 /// virtual list response control.
367                 /// </param>
368                 public LdapVirtualListControl(int startIndex, int beforeCount, int afterCount, int contentCount, System.String context):base(requestOID, true, null)
369                 {
370                         
371                         
372                         /* Save off the fields in local variables
373                         */
374                         m_beforeCount = beforeCount;
375                         m_afterCount = afterCount;
376                         m_startIndex = startIndex;
377                         m_contentCount = contentCount;
378                         m_context = context;
379                         
380                         /* Call private method to build the ASN.1 encoded request packet.
381                         */
382                         BuildIndexedVLVRequest();
383                         
384                         /* Set the request data field in the in the parent LdapControl to
385                         * the ASN.1 encoded value of this control.  This encoding will be
386                         * appended to the search request when the control is sent.
387                         */
388                         setValue(m_vlvRequest.getEncoding(new LBEREncoder()));
389                         return ;
390                 }
391                 
392                 /// <summary>Private method used to construct the ber encoded control
393                 /// Used only when using the Indexed mode of VLV Control
394                 /// </summary>
395                 private void  BuildIndexedVLVRequest()
396                 {
397                         /* Create a new Asn1Sequence object */
398                         m_vlvRequest = new Asn1Sequence(4);
399                         
400                         /* Add the beforeCount and afterCount fields to the sequence */
401                         m_vlvRequest.add(new Asn1Integer(m_beforeCount));
402                         m_vlvRequest.add(new Asn1Integer(m_afterCount));
403                         
404                         /* The next field is dependent on the type of indexing being used.
405                         * An "indexed" VLV request uses a ASN.1 SEQUENCE to index to the
406                         * correct object in the list.  Encode the ASN.1 CHOICE corresponding
407                         * to this option (as indicated by the byoffset fieldin the ASN.1.
408                         */
409                         Asn1Sequence byoffset = new Asn1Sequence(2);
410                         byoffset.add(new Asn1Integer(m_startIndex));
411                         byoffset.add(new Asn1Integer(m_contentCount)); ;
412                         
413                         /* Add the ASN.1 sequence to the encoded data
414                         */
415                         m_vlvRequest.add(new Asn1Tagged(new Asn1Identifier(Asn1Identifier.CONTEXT, true, BYOFFSET), byoffset, false));
416                         
417                         /* Add the optional context string if one is available.
418                         */
419                         if ((System.Object) m_context != null)
420                                 m_vlvRequest.add(new Asn1OctetString(m_context));
421                         
422                         return ;
423                 }
424                 
425                 
426                 
427                 /// <summary> Sets the center or starting list index to return, and the number of
428                 /// results before and after.
429                 /// 
430                 /// 
431                 /// </summary>
432                 /// <param name="listIndex">       The center or starting list index to be
433                 /// returned. 
434                 /// 
435                 /// </param>
436                 /// <param name="beforeCount">       The number of entries before "listIndex" to be
437                 /// returned. 
438                 /// 
439                 /// </param>
440                 /// <param name="afterCount">       The number of entries after "listIndex" to be
441                 /// returned. 
442                 /// </param>
443                 public virtual void  setRange(int listIndex, int beforeCount, int afterCount)
444                 {
445                         
446                         /* Save off the fields in local variables
447                         */
448                         m_beforeCount = beforeCount;
449                         m_afterCount = afterCount;
450                         m_startIndex = listIndex;
451                         
452                         /* since we just changed a field we need to rebuild the ber
453                         * encoded control
454                         */
455                         BuildIndexedVLVRequest();
456                         
457                         /* Set the request data field in the in the parent LdapControl to
458                         * the ASN.1 encoded value of this control.  This encoding will be
459                         * appended to the search request when the control is sent.
460                         */
461                         setValue(m_vlvRequest.getEncoding(new LBEREncoder()));
462                 }
463                 
464                 // PROPOSED ADDITION TO NEXT VERSION OF DRAFT (v7)
465                 /// <summary> Sets the center or starting list index to return, and the number of
466                 /// results before and after.
467                 /// 
468                 /// 
469                 /// </summary>
470                 /// <param name="jumpTo">A search expression that defines the first
471                 /// element to be returned in the virtual search results. The filter
472                 /// expression in the search operation itself may be, for example,
473                 /// "objectclass=person" and the jumpTo expression in the virtual
474                 /// list control may be "cn=m*", to retrieve a subset of entries
475                 /// starting at or centered around those with a common name
476                 /// beginning with the letter "M".
477                 /// 
478                 /// </param>
479                 /// <param name="beforeCount">   The number of entries before "listIndex" to be
480                 /// returned.
481                 /// 
482                 /// </param>
483                 /// <param name="afterCount">The number of entries after "listIndex" to be
484                 /// returned.
485                 /// </param>
486                 
487                 public virtual void  setRange(System.String jumpTo, int beforeCount, int afterCount)
488                 {
489                         /* Save off the fields in local variables
490                         */
491                         m_beforeCount = beforeCount;
492                         m_afterCount = afterCount;
493                         m_jumpTo = jumpTo;
494                         
495                         /* since we just changed a field we need to rebuild the ber
496                         * encoded control
497                         */
498                         BuildTypedVLVRequest();
499                         
500                         /* Set the request data field in the in the parent LdapControl to
501                         * the ASN.1 encoded value of this control.  This encoding will be
502                         * appended to the search request when the control is sent.
503                         */
504                         setValue(m_vlvRequest.getEncoding(new LBEREncoder()));
505                 }
506                 static LdapVirtualListControl()
507                 {
508                         /*
509                         * This is where we register the control responses
510                         */
511                         {
512                                 /* Register the VLV Sort Control class which is returned by the server
513                                 * in response to a VLV Sort Request
514                                 */
515                                 try
516                                 {
517                                         LdapControl.register(responseOID, System.Type.GetType("Novell.Directory.Ldap.Controls.LdapVirtualListResponse"));
518                                 }
519                                 catch (System.Exception e)
520                                 {
521                                 }
522                         }
523                 }
524         }
525 }