001 /*
002 * Copyright 2007-2013 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2008-2013 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021 package com.unboundid.ldap.sdk.controls;
022
023
024
025 import com.unboundid.asn1.ASN1Element;
026 import com.unboundid.asn1.ASN1Integer;
027 import com.unboundid.asn1.ASN1OctetString;
028 import com.unboundid.asn1.ASN1Sequence;
029 import com.unboundid.ldap.sdk.Control;
030 import com.unboundid.ldap.sdk.LDAPException;
031 import com.unboundid.ldap.sdk.ResultCode;
032 import com.unboundid.util.NotMutable;
033 import com.unboundid.util.ThreadSafety;
034 import com.unboundid.util.ThreadSafetyLevel;
035
036 import static com.unboundid.ldap.sdk.controls.ControlMessages.*;
037 import static com.unboundid.util.Debug.*;
038 import static com.unboundid.util.StaticUtils.*;
039 import static com.unboundid.util.Validator.*;
040
041
042
043 /**
044 * This class provides an implementation of the LDAP virtual list view (VLV)
045 * request control as defined in draft-ietf-ldapext-ldapv3-vlv. This control
046 * may be used to retrieve arbitrary "pages" of entries from the complete set of
047 * search results. It is similar to the {@link SimplePagedResultsControl}, with
048 * the exception that the simple paged results control requires scrolling
049 * through the results in sequential order, while the VLV control allows
050 * starting and resuming at any arbitrary point in the result set. The starting
051 * point may be specified using either a positional offset, or based on the
052 * first entry with a value that is greater than or equal to a specified value.
053 * <BR><BR>
054 * When the start of the result set is to be specified using an offset, then the
055 * virtual list view request control should include the following elements:
056 * <UL>
057 * <LI>{@code targetOffset} -- The position in the result set of the entry to
058 * target for the next page of results to return. Note that the offset is
059 * one-based (so the first entry has offset 1, the second entry has offset
060 * 2, etc.).</LI>
061 * <LI>{@code beforeCount} -- The number of entries before the entry specified
062 * as the target offset that should be retrieved.</LI>
063 * <LI>{@code afterCount} -- The number of entries after the entry specified
064 * as the target offset that should be retrieved.</LI>
065 * <LI>{@code contentCount} -- The estimated total number of entries that
066 * are in the total result set. This should be zero for the first request
067 * in a VLV search sequence, but should be the value returned by the
068 * server in the corresponding response control for subsequent searches as
069 * part of the VLV sequence.</LI>
070 * <LI>{@code contextID} -- This is an optional cookie that may be used to
071 * help the server resume processing on a VLV search. It should be absent
072 * from the initial request, but for subsequent requests should be the
073 * value returned in the previous VLV response control.</LI>
074 * </UL>
075 * When the start of the result set is to be specified using a search string,
076 * then the virtual list view request control should include the following
077 * elements:
078 * <UL>
079 * <LI>{@code assertionValue} -- The value that specifies the start of the
080 * page of results to retrieve. The target entry will be the first entry
081 * in which the value for the primary sort attribute is greater than or
082 * equal to this assertion value.</LI>
083 * <LI>{@code beforeCount} -- The number of entries before the entry specified
084 * by the assertion value that should be retrieved.</LI>
085 * <LI>{@code afterCount} -- The number of entries after the entry specified
086 * by the assertion value that should be retrieved.</LI>
087 * <LI>{@code contentCount} -- The estimated total number of entries that
088 * are in the total result set. This should be zero for the first request
089 * in a VLV search sequence, but should be the value returned by the
090 * server in the corresponding response control for subsequent searches as
091 * part of the VLV sequence.</LI>
092 * <LI>{@code contextID} -- This is an optional cookie that may be used to
093 * help the server resume processing on a VLV search. It should be absent
094 * from the initial request, but for subsequent requests should be the
095 * value returned in the previous VLV response control.</LI>
096 * </UL>
097 * Note that the virtual list view request control may only be included in a
098 * search request if that search request also includes the
099 * {@link ServerSideSortRequestControl}. This is necessary to ensure that a
100 * consistent order is used for the resulting entries.
101 * <BR><BR>
102 * If the search is successful, then the search result done response may include
103 * a {@link VirtualListViewResponseControl} to provide information about the
104 * state of the virtual list view processing.
105 * <BR><BR>
106 * <H2>Example</H2>
107 * The following example demonstrates the use of the virtual list view request
108 * control to iterate through all users in the "Sales" department, retrieving
109 * up to 10 entries at a time:
110 * <PRE>
111 * ServerSideSortRequestControl sortRequest =
112 * new ServerSideSortRequestControl(new SortKey("sn"),
113 * new SortKey("givenName"));
114 * SearchRequest searchRequest =
115 * new SearchRequest("dc=example,dc=com", SearchScope.SUB, "(ou=Sales)");
116 *
117 * int offset = 1;
118 * int contentCount = 0;
119 * ASN1OctetString contextID = null;
120 * do
121 * {
122 * VirtualListViewRequestControl vlvRequest =
123 * new VirtualListViewRequestControl(offset, 0, 9, contentCount,
124 * contextID);
125 * searchRequest.setControls(new Control[] { sortRequest, vlvRequest });
126 * SearchResult searchResult = connection.search();
127 *
128 * // Do something with the entries that are returned.
129 *
130 * contentCount = -1;
131 * VirtualListViewResponseControl c =
132 * VirtualListViewResponseControl.get(searchResult);
133 * if (c != null)
134 * {
135 * contentCount = c.getContentCount();
136 * contextID = c.getContextID();
137 * }
138 *
139 * offset += 10;
140 * } while (offset <= contentCount);
141 * </PRE>
142 */
143 @NotMutable()
144 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
145 public final class VirtualListViewRequestControl
146 extends Control
147 {
148 /**
149 * The OID (2.16.840.1.113730.3.4.9) for the virtual list view request
150 * control.
151 */
152 public static final String VIRTUAL_LIST_VIEW_REQUEST_OID =
153 "2.16.840.1.113730.3.4.9";
154
155
156
157 /**
158 * The BER type that will be used for the target element when the target is
159 * specified by offset.
160 */
161 private static final byte TARGET_TYPE_OFFSET = (byte) 0xA0;
162
163
164
165 /**
166 * The BER type that will be used for the target element when the target is
167 * specified by an assertion value.
168 */
169 private static final byte TARGET_TYPE_GREATER_OR_EQUAL = (byte) 0x81;
170
171
172
173 /**
174 * The serial version UID for this serializable class.
175 */
176 private static final long serialVersionUID = 4348423177859960815L;
177
178
179
180 // The assertion value that will be used to identify the start of the
181 // requested page of results for a greater-or-equal target type.
182 private final ASN1OctetString assertionValue;
183
184 // The context ID that may be used to help the server continue in the same
185 // result set for subsequent searches.
186 private final ASN1OctetString contextID;
187
188 // The maximum number of entries to return after the target entry.
189 private final int afterCount;
190
191 // The maximum number of entries to return before the target entry.
192 private final int beforeCount;
193
194 // The estimated number of entries in the complete result set.
195 private final int contentCount;
196
197 // The position of the entry at the start of the requested page of results for
198 // an offset-based target type.
199 private final int targetOffset;
200
201
202
203 /**
204 * Creates a new virtual list view request control that will identify the
205 * beginning of the result set by a target offset. It will be marked
206 * critical.
207 *
208 * @param targetOffset The position of the entry that should be used as the
209 * start of the result set.
210 * @param beforeCount The maximum number of entries that should be returned
211 * before the entry with the specified target offset.
212 * @param afterCount The maximum number of entries that should be returned
213 * after the entry with the specified target offset.
214 * @param contentCount The estimated number of entries in the result set.
215 * For the first request in a series of searches with
216 * the VLV control, it should be zero. For subsequent
217 * searches in the VLV sequence, it should be the
218 * content count included in the response control from
219 * the previous search.
220 * @param contextID The context ID that may be used to help the server
221 * continue in the same result set for subsequent
222 * searches. For the first request in a series of
223 * searches with the VLV control, it should be
224 * {@code null}. For subsequent searches in the VLV
225 * sequence, it should be the (possibly {@code null}
226 * context ID included in the response control from the
227 * previous search.
228 */
229 public VirtualListViewRequestControl(final int targetOffset,
230 final int beforeCount, final int afterCount,
231 final int contentCount, final ASN1OctetString contextID)
232 {
233 this(targetOffset, beforeCount, afterCount, contentCount, contextID, true);
234 }
235
236
237
238 /**
239 * Creates a new virtual list view request control that will identify the
240 * beginning of the result set by an assertion value. It will be marked
241 * critical.
242 *
243 * @param assertionValue The assertion value that will be used to identify
244 * the start of the result set. The target entry will
245 * be the first entry with a value for the primary
246 * sort attribute that is greater than or equal to
247 * this assertion value. It must not be {@code null}.
248 * @param beforeCount The maximum number of entries that should be
249 * returned before the first entry with a value
250 * greater than or equal to the provided assertion
251 * value.
252 * @param afterCount The maximum number of entries that should be
253 * returned after the first entry with a value
254 * greater than or equal to the provided assertion
255 * value.
256 * @param contextID The context ID that may be used to help the server
257 * continue in the same result set for subsequent
258 * searches. For the first request in a series of
259 * searches with the VLV control, it should be
260 * {@code null}. For subsequent searches in the VLV
261 * sequence, it should be the (possibly {@code null}
262 * context ID included in the response control from
263 * the previous search.
264 */
265 public VirtualListViewRequestControl(final String assertionValue,
266 final int beforeCount, final int afterCount,
267 final ASN1OctetString contextID)
268 {
269 this(new ASN1OctetString(assertionValue), beforeCount, afterCount,
270 contextID, true);
271 }
272
273
274
275 /**
276 * Creates a new virtual list view request control that will identify the
277 * beginning of the result set by an assertion value. It will be marked
278 * critical.
279 *
280 * @param assertionValue The assertion value that will be used to identify
281 * the start of the result set. The target entry will
282 * be the first entry with a value for the primary
283 * sort attribute that is greater than or equal to
284 * this assertion value. It must not be {@code null}.
285 * @param beforeCount The maximum number of entries that should be
286 * returned before the first entry with a value
287 * greater than or equal to the provided assertion
288 * value.
289 * @param afterCount The maximum number of entries that should be
290 * returned after the first entry with a value
291 * greater than or equal to the provided assertion
292 * value.
293 * @param contextID The context ID that may be used to help the server
294 * continue in the same result set for subsequent
295 * searches. For the first request in a series of
296 * searches with the VLV control, it should be
297 * {@code null}. For subsequent searches in the VLV
298 * sequence, it should be the (possibly {@code null}
299 * context ID included in the response control from
300 * the previous search.
301 */
302 public VirtualListViewRequestControl(final byte[] assertionValue,
303 final int beforeCount, final int afterCount,
304 final ASN1OctetString contextID)
305 {
306 this(new ASN1OctetString(assertionValue), beforeCount, afterCount,
307 contextID, true);
308 }
309
310
311
312 /**
313 * Creates a new virtual list view request control that will identify the
314 * beginning of the result set by an assertion value. It will be marked
315 * critical.
316 *
317 * @param assertionValue The assertion value that will be used to identify
318 * the start of the result set. The target entry will
319 * be the first entry with a value for the primary
320 * sort attribute that is greater than or equal to
321 * this assertion value. It must not be {@code null}.
322 * @param beforeCount The maximum number of entries that should be
323 * returned before the first entry with a value
324 * greater than or equal to the provided assertion
325 * value.
326 * @param afterCount The maximum number of entries that should be
327 * returned after the first entry with a value
328 * greater than or equal to the provided assertion
329 * value.
330 * @param contextID The context ID that may be used to help the server
331 * continue in the same result set for subsequent
332 * searches. For the first request in a series of
333 * searches with the VLV control, it should be
334 * {@code null}. For subsequent searches in the VLV
335 * sequence, it should be the (possibly {@code null}
336 * context ID included in the response control from
337 * the previous search.
338 */
339 public VirtualListViewRequestControl(final ASN1OctetString assertionValue,
340 final int beforeCount, final int afterCount,
341 final ASN1OctetString contextID)
342 {
343 this(assertionValue, beforeCount, afterCount, contextID, true);
344 }
345
346
347
348 /**
349 * Creates a new virtual list view request control that will identify the
350 * beginning of the result set by a target offset.
351 *
352 * @param targetOffset The position of the entry that should be used as the
353 * start of the result set.
354 * @param beforeCount The maximum number of entries that should be returned
355 * before the entry with the specified target offset.
356 * @param afterCount The maximum number of entries that should be returned
357 * after the entry with the specified target offset.
358 * @param contentCount The estimated number of entries in the result set.
359 * For the first request in a series of searches with
360 * the VLV control, it should be zero. For subsequent
361 * searches in the VLV sequence, it should be the
362 * content count included in the response control from
363 * the previous search.
364 * @param contextID The context ID that may be used to help the server
365 * continue in the same result set for subsequent
366 * searches. For the first request in a series of
367 * searches with the VLV control, it should be
368 * {@code null}. For subsequent searches in the VLV
369 * sequence, it should be the (possibly {@code null}
370 * context ID included in the response control from the
371 * previous search.
372 * @param isCritical Indicates whether this control should be marked
373 * critical.
374 */
375 public VirtualListViewRequestControl(final int targetOffset,
376 final int beforeCount, final int afterCount,
377 final int contentCount, final ASN1OctetString contextID,
378 final boolean isCritical)
379 {
380 super(VIRTUAL_LIST_VIEW_REQUEST_OID, isCritical,
381 encodeValue(targetOffset, beforeCount, afterCount, contentCount,
382 contextID));
383
384 this.targetOffset = targetOffset;
385 this.beforeCount = beforeCount;
386 this.afterCount = afterCount;
387 this.contentCount = contentCount;
388 this.contextID = contextID;
389
390 assertionValue = null;
391 }
392
393
394
395 /**
396 * Creates a new virtual list view request control that will identify the
397 * beginning of the result set by an assertion value. It will be marked
398 * critical.
399 *
400 * @param assertionValue The assertion value that will be used to identify
401 * the start of the result set. The target entry will
402 * be the first entry with a value for the primary
403 * sort attribute that is greater than or equal to
404 * this assertion value. It must not be {@code null}.
405 * @param beforeCount The maximum number of entries that should be
406 * returned before the first entry with a value
407 * greater than or equal to the provided assertion
408 * value.
409 * @param afterCount The maximum number of entries that should be
410 * returned after the first entry with a value
411 * greater than or equal to the provided assertion
412 * value.
413 * @param contextID The context ID that may be used to help the server
414 * continue in the same result set for subsequent
415 * searches. For the first request in a series of
416 * searches with the VLV control, it should be
417 * {@code null}. For subsequent searches in the VLV
418 * sequence, it should be the (possibly {@code null}
419 * context ID included in the response control from
420 * the previous search.
421 * @param isCritical Indicates whether this control should be marked
422 * critical.
423 */
424 public VirtualListViewRequestControl(final String assertionValue,
425 final int beforeCount, final int afterCount,
426 final ASN1OctetString contextID, final boolean isCritical)
427 {
428 this(new ASN1OctetString(assertionValue), beforeCount, afterCount,
429 contextID, isCritical);
430 }
431
432
433
434 /**
435 * Creates a new virtual list view request control that will identify the
436 * beginning of the result set by an assertion value. It will be marked
437 * critical.
438 *
439 * @param assertionValue The assertion value that will be used to identify
440 * the start of the result set. The target entry will
441 * be the first entry with a value for the primary
442 * sort attribute that is greater than or equal to
443 * this assertion value. It must not be {@code null}.
444 * @param beforeCount The maximum number of entries that should be
445 * returned before the first entry with a value
446 * greater than or equal to the provided assertion
447 * value.
448 * @param afterCount The maximum number of entries that should be
449 * returned after the first entry with a value
450 * greater than or equal to the provided assertion
451 * value.
452 * @param contextID The context ID that may be used to help the server
453 * continue in the same result set for subsequent
454 * searches. For the first request in a series of
455 * searches with the VLV control, it should be
456 * {@code null}. For subsequent searches in the VLV
457 * sequence, it should be the (possibly {@code null}
458 * context ID included in the response control from
459 * the previous search.
460 * @param isCritical Indicates whether this control should be marked
461 * critical.
462 */
463 public VirtualListViewRequestControl(final byte[] assertionValue,
464 final int beforeCount, final int afterCount,
465 final ASN1OctetString contextID, final boolean isCritical)
466 {
467 this(new ASN1OctetString(assertionValue), beforeCount, afterCount,
468 contextID, isCritical);
469 }
470
471
472
473 /**
474 * Creates a new virtual list view request control that will identify the
475 * beginning of the result set by an assertion value. It will be marked
476 * critical.
477 *
478 * @param assertionValue The assertion value that will be used to identify
479 * the start of the result set. The target entry will
480 * be the first entry with a value for the primary
481 * sort attribute that is greater than or equal to
482 * this assertion value. It must not be {@code null}.
483 * @param beforeCount The maximum number of entries that should be
484 * returned before the first entry with a value
485 * greater than or equal to the provided assertion
486 * value.
487 * @param afterCount The maximum number of entries that should be
488 * returned after the first entry with a value
489 * greater than or equal to the provided assertion
490 * value.
491 * @param contextID The context ID that may be used to help the server
492 * continue in the same result set for subsequent
493 * searches. For the first request in a series of
494 * searches with the VLV control, it should be
495 * {@code null}. For subsequent searches in the VLV
496 * sequence, it should be the (possibly {@code null}
497 * context ID included in the response control from
498 * the previous search.
499 * @param isCritical Indicates whether this control should be marked
500 * critical.
501 */
502 public VirtualListViewRequestControl(final ASN1OctetString assertionValue,
503 final int beforeCount, final int afterCount,
504 final ASN1OctetString contextID, final boolean isCritical)
505 {
506 super(VIRTUAL_LIST_VIEW_REQUEST_OID, isCritical,
507 encodeValue(assertionValue, beforeCount, afterCount, contextID));
508
509 this.assertionValue = assertionValue;
510 this.beforeCount = beforeCount;
511 this.afterCount = afterCount;
512 this.contextID = contextID;
513
514 targetOffset = -1;
515 contentCount = -1;
516 }
517
518
519
520 /**
521 * Creates a new virtual list view request control which is decoded from the
522 * provided generic control.
523 *
524 * @param control The generic control to be decoded as a virtual list view
525 * request control.
526 *
527 * @throws LDAPException If the provided control cannot be decoded as a
528 * virtual list view request control.
529 */
530 public VirtualListViewRequestControl(final Control control)
531 throws LDAPException
532 {
533 super(control);
534
535 final ASN1OctetString value = control.getValue();
536 if (value == null)
537 {
538 throw new LDAPException(ResultCode.DECODING_ERROR,
539 ERR_VLV_REQUEST_NO_VALUE.get());
540 }
541
542 try
543 {
544 final ASN1Element valueElement = ASN1Element.decode(value.getValue());
545 final ASN1Element[] elements =
546 ASN1Sequence.decodeAsSequence(valueElement).elements();
547
548 beforeCount = ASN1Integer.decodeAsInteger(elements[0]).intValue();
549 afterCount = ASN1Integer.decodeAsInteger(elements[1]).intValue();
550
551 switch (elements[2].getType())
552 {
553 case TARGET_TYPE_OFFSET:
554 assertionValue = null;
555 final ASN1Element[] offsetElements =
556 ASN1Sequence.decodeAsSequence(elements[2]).elements();
557 targetOffset =
558 ASN1Integer.decodeAsInteger(offsetElements[0]).intValue();
559 contentCount =
560 ASN1Integer.decodeAsInteger(offsetElements[1]).intValue();
561 break;
562
563 case TARGET_TYPE_GREATER_OR_EQUAL:
564 assertionValue = ASN1OctetString.decodeAsOctetString(elements[2]);
565 targetOffset = -1;
566 contentCount = -1;
567 break;
568
569 default:
570 throw new LDAPException(ResultCode.DECODING_ERROR,
571 ERR_VLV_REQUEST_INVALID_ELEMENT_TYPE.get(
572 toHex(elements[2].getType())));
573 }
574
575 if (elements.length == 4)
576 {
577 contextID = ASN1OctetString.decodeAsOctetString(elements[3]);
578 }
579 else
580 {
581 contextID = null;
582 }
583 }
584 catch (LDAPException le)
585 {
586 debugException(le);
587 throw le;
588 }
589 catch (Exception e)
590 {
591 debugException(e);
592 throw new LDAPException(ResultCode.DECODING_ERROR,
593 ERR_VLV_REQUEST_CANNOT_DECODE.get(e), e);
594 }
595 }
596
597
598
599 /**
600 * Encodes the provided information into an octet string that can be used as
601 * the value for this control.
602 *
603 * @param targetOffset The position of the entry that should be used as the
604 * start of the result set.
605 * @param beforeCount The maximum number of entries that should be returned
606 * before the entry with the specified target offset.
607 * @param afterCount The maximum number of entries that should be returned
608 * after the entry with the specified target offset.
609 * @param contentCount The estimated number of entries in the result set.
610 * For the first request in a series of searches with
611 * the VLV control, it should be zero. For subsequent
612 * searches in the VLV sequence, it should be the
613 * content count included in the response control from
614 * the previous search.
615 * @param contextID The context ID that may be used to help the server
616 * continue in the same result set for subsequent
617 * searches. For the first request in a series of
618 * searches with the VLV control, it should be
619 * {@code null}. For subsequent searches in the VLV
620 * sequence, it should be the (possibly {@code null}
621 * context ID included in the response control from the
622 * previous search.
623 *
624 * @return An ASN.1 octet string that can be used as the value for this
625 * control.
626 */
627 private static ASN1OctetString encodeValue(final int targetOffset,
628 final int beforeCount,
629 final int afterCount,
630 final int contentCount,
631 final ASN1OctetString contextID)
632 {
633 final ASN1Element[] targetElements =
634 {
635 new ASN1Integer(targetOffset),
636 new ASN1Integer(contentCount)
637 };
638
639 final ASN1Element[] vlvElements;
640 if (contextID == null)
641 {
642 vlvElements = new ASN1Element[]
643 {
644 new ASN1Integer(beforeCount),
645 new ASN1Integer(afterCount),
646 new ASN1Sequence(TARGET_TYPE_OFFSET, targetElements)
647 };
648 }
649 else
650 {
651 vlvElements = new ASN1Element[]
652 {
653 new ASN1Integer(beforeCount),
654 new ASN1Integer(afterCount),
655 new ASN1Sequence(TARGET_TYPE_OFFSET, targetElements),
656 contextID
657 };
658 }
659
660 return new ASN1OctetString(new ASN1Sequence(vlvElements).encode());
661 }
662
663
664
665 /**
666 * Encodes the provided information into an octet string that can be used as
667 * the value for this control.
668 *
669 * @param assertionValue The assertion value that will be used to identify
670 * the start of the result set. The target entry will
671 * be the first entry with a value for the primary
672 * sort attribute that is greater than or equal to
673 * this assertion value.
674 * @param beforeCount The maximum number of entries that should be
675 * returned before the first entry with a value
676 * greater than or equal to the provided assertion
677 * value.
678 * @param afterCount The maximum number of entries that should be
679 * returned after the first entry with a value
680 * greater than or equal to the provided assertion
681 * value.
682 * @param contextID The context ID that may be used to help the server
683 * continue in the same result set for subsequent
684 * searches. For the first request in a series of
685 * searches with the VLV control, it should be
686 * {@code null}. For subsequent searches in the VLV
687 * sequence, it should be the (possibly {@code null}
688 * context ID included in the response control from
689 * the previous search.
690 *
691 * @return An ASN.1 octet string that can be used as the value for this
692 * control.
693 */
694 private static ASN1OctetString encodeValue(
695 final ASN1OctetString assertionValue,
696 final int beforeCount,
697 final int afterCount,
698 final ASN1OctetString contextID)
699 {
700 ensureNotNull(assertionValue);
701
702 final ASN1Element[] vlvElements;
703 if (contextID == null)
704 {
705 vlvElements = new ASN1Element[]
706 {
707 new ASN1Integer(beforeCount),
708 new ASN1Integer(afterCount),
709 new ASN1OctetString(TARGET_TYPE_GREATER_OR_EQUAL,
710 assertionValue.getValue())
711 };
712 }
713 else
714 {
715 vlvElements = new ASN1Element[]
716 {
717 new ASN1Integer(beforeCount),
718 new ASN1Integer(afterCount),
719 new ASN1OctetString(TARGET_TYPE_GREATER_OR_EQUAL,
720 assertionValue.getValue()),
721 contextID
722 };
723 }
724
725 return new ASN1OctetString(new ASN1Sequence(vlvElements).encode());
726 }
727
728
729
730 /**
731 * Retrieves the target offset position for this virtual list view request
732 * control, if applicable.
733 *
734 * @return The target offset position for this virtual list view request
735 * control, or -1 if the target is specified by an assertion value.
736 */
737 public int getTargetOffset()
738 {
739 return targetOffset;
740 }
741
742
743
744 /**
745 * Retrieves the string representation of the assertion value for this virtual
746 * list view request control, if applicable.
747 *
748 * @return The string representation of the assertion value for this virtual
749 * list view request control, or {@code null} if the target is
750 * specified by offset.
751 */
752 public String getAssertionValueString()
753 {
754 if (assertionValue == null)
755 {
756 return null;
757 }
758 else
759 {
760 return assertionValue.stringValue();
761 }
762 }
763
764
765
766 /**
767 * Retrieves the byte array representation of the assertion value for this
768 * virtual list view request control, if applicable.
769 *
770 * @return The byte array representation of the assertion value for this
771 * virtual list view request control, or {@code null} if the target
772 * is specified by offset.
773 */
774 public byte[] getAssertionValueBytes()
775 {
776 if (assertionValue == null)
777 {
778 return null;
779 }
780 else
781 {
782 return assertionValue.getValue();
783 }
784 }
785
786
787
788 /**
789 * Retrieves the assertion value for this virtual list view request control,
790 * if applicable.
791 *
792 * @return The assertion value for this virtual list view request control, or
793 * {@code null} if the target is specified by offset.
794 */
795 public ASN1OctetString getAssertionValue()
796 {
797 return assertionValue;
798 }
799
800
801
802 /**
803 * Retrieves the number of entries that should be retrieved before the target
804 * entry.
805 *
806 * @return The number of entries that should be retrieved before the target
807 * entry.
808 */
809 public int getBeforeCount()
810 {
811 return beforeCount;
812 }
813
814
815
816 /**
817 * Retrieves the number of entries that should be retrieved after the target
818 * entry.
819 *
820 * @return The number of entries that should be retrieved after the target
821 * entry.
822 */
823 public int getAfterCount()
824 {
825 return afterCount;
826 }
827
828
829
830 /**
831 * Retrieves the estimated number of entries in the result set, if applicable.
832 *
833 * @return The estimated number of entries in the result set, zero if it
834 * is not known (for the first search in a sequence where the
835 * target is specified by offset), or -1 if the target is specified
836 * by an assertion value.
837 */
838 public int getContentCount()
839 {
840 return contentCount;
841 }
842
843
844
845 /**
846 * Retrieves the context ID for this virtual list view request control, if
847 * available.
848 *
849 * @return The context ID for this virtual list view request control, or
850 * {@code null} if there is none.
851 */
852 public ASN1OctetString getContextID()
853 {
854 return contextID;
855 }
856
857
858
859 /**
860 * {@inheritDoc}
861 */
862 @Override()
863 public String getControlName()
864 {
865 return INFO_CONTROL_NAME_VLV_REQUEST.get();
866 }
867
868
869
870 /**
871 * {@inheritDoc}
872 */
873 @Override()
874 public void toString(final StringBuilder buffer)
875 {
876 buffer.append("VirtualListViewRequestControl(beforeCount=");
877 buffer.append(beforeCount);
878 buffer.append(", afterCount=");
879 buffer.append(afterCount);
880
881 if (assertionValue == null)
882 {
883 buffer.append(", targetOffset=");
884 buffer.append(targetOffset);
885 buffer.append(", contentCount=");
886 buffer.append(contentCount);
887 }
888 else
889 {
890 buffer.append(", assertionValue='");
891 buffer.append(assertionValue.stringValue());
892 buffer.append('\'');
893 }
894
895 buffer.append(", isCritical=");
896 buffer.append(isCritical());
897 buffer.append(')');
898 }
899 }