From 4b976b00d90e98ae2807d7bdc9efb79a4ce75751 Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Mon, 30 Apr 2007 16:24:15 +0000
Subject: [PATCH] Implement support for the virtual list view (VLV) control as defined in draft-ietf-ldapext-ldapv3-vlv. This can be used to retrieve a specified page of a search result set. Any result set that can be used with server-side sorting can also be used with VLV. The ldapsearch tool has also been updated to support this control.
---
opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java | 135 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 135 insertions(+), 0 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java b/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java
index adbb71c..b799511 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java
@@ -46,6 +46,9 @@
import org.opends.server.controls.PersistentSearchChangeType;
import org.opends.server.controls.PersistentSearchControl;
import org.opends.server.controls.ServerSideSortRequestControl;
+import org.opends.server.controls.ServerSideSortResponseControl;
+import org.opends.server.controls.VLVRequestControl;
+import org.opends.server.controls.VLVResponseControl;
import org.opends.server.core.DirectoryServer;
import org.opends.server.util.Base64;
import org.opends.server.util.PasswordReader;
@@ -63,6 +66,7 @@
import org.opends.server.protocols.ldap.LDAPControl;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.protocols.ldap.LDAPMessage;
+import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.protocols.ldap.SearchRequestProtocolOp;
import org.opends.server.protocols.ldap.SearchResultDoneProtocolOp;
import org.opends.server.protocols.ldap.SearchResultEntryProtocolOp;
@@ -301,6 +305,66 @@
errorMessage = searchOp.getErrorMessage();
matchedDN = searchOp.getMatchedDN();
+ for (LDAPControl c : responseMessage.getControls())
+ {
+ if (c.getOID().equals(OID_SERVER_SIDE_SORT_RESPONSE_CONTROL))
+ {
+ try
+ {
+ ServerSideSortResponseControl sortResponse =
+ ServerSideSortResponseControl.decodeControl(
+ c.getControl());
+ int rc = sortResponse.getResultCode();
+ if (rc != LDAPResultCode.SUCCESS)
+ {
+ int msgID = MSGID_LDAPSEARCH_SORT_ERROR;
+ String msg = getMessage(msgID,
+ LDAPResultCode.toString(rc));
+ err.println(msg);
+ }
+ }
+ catch (Exception e)
+ {
+ int msgID = MSGID_LDAPSEARCH_CANNOT_DECODE_SORT_RESPONSE;
+ String msg = getMessage(msgID, getExceptionMessage(e));
+ err.println(msg);
+ }
+ }
+ else if (c.getOID().equals(OID_VLV_RESPONSE_CONTROL))
+ {
+ try
+ {
+ VLVResponseControl vlvResponse =
+ VLVResponseControl.decodeControl(c.getControl());
+ int rc = vlvResponse.getVLVResultCode();
+ if (rc == LDAPResultCode.SUCCESS)
+ {
+ int msgID = MSGID_LDAPSEARCH_VLV_TARGET_OFFSET;
+ String msg = getMessage(msgID,
+ vlvResponse.getTargetPosition());
+ out.println(msg);
+
+ msgID = MSGID_LDAPSEARCH_VLV_CONTENT_COUNT;
+ msg = getMessage(msgID, vlvResponse.getContentCount());
+ out.println(msg);
+ }
+ else
+ {
+ int msgID = MSGID_LDAPSEARCH_VLV_ERROR;
+ String msg = getMessage(msgID,
+ LDAPResultCode.toString(rc));
+ err.println(msg);
+ }
+ }
+ catch (Exception e)
+ {
+ int msgID = MSGID_LDAPSEARCH_CANNOT_DECODE_VLV_RESPONSE;
+ String msg = getMessage(msgID, getExceptionMessage(e));
+ err.println(msg);
+ }
+ }
+ }
+
break;
default:
// FIXME - throw exception?
@@ -606,6 +670,7 @@
StringArgument sortOrder = null;
StringArgument trustStorePath = null;
StringArgument trustStorePassword = null;
+ StringArgument vlvDescriptor = null;
// Create the command-line argument parser for use with this program.
@@ -795,6 +860,13 @@
MSGID_DESCRIPTION_SORT_ORDER);
argParser.addArgument(sortOrder);
+ vlvDescriptor =
+ new StringArgument("vlvdescriptor", 'G', "virtualListView", false,
+ false, true,
+ "{before:after:index:count | before:after:value}",
+ null, null, MSGID_DESCRIPTION_VLV);
+ argParser.addArgument(vlvDescriptor);
+
controlStr =
new StringArgument("control", 'J', "control", false, true, true,
"{controloid[:criticality[:value|::b64value|:<fileurl]]}",
@@ -1284,6 +1356,69 @@
}
}
+ if (vlvDescriptor.isPresent())
+ {
+ if (! sortOrder.isPresent())
+ {
+ int msgID = MSGID_LDAPSEARCH_VLV_REQUIRES_SORT;
+ String message = getMessage(msgID, vlvDescriptor.getLongIdentifier(),
+ sortOrder.getLongIdentifier());
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ return 1;
+ }
+
+ StringTokenizer tokenizer =
+ new StringTokenizer(vlvDescriptor.getValue(), ":");
+ int numTokens = tokenizer.countTokens();
+ if (numTokens == 3)
+ {
+ try
+ {
+ int beforeCount = Integer.parseInt(tokenizer.nextToken());
+ int afterCount = Integer.parseInt(tokenizer.nextToken());
+ ASN1OctetString assertionValue =
+ new ASN1OctetString(tokenizer.nextToken());
+ searchOptions.getControls().add(
+ new LDAPControl(new VLVRequestControl(beforeCount, afterCount,
+ assertionValue)));
+ }
+ catch (Exception e)
+ {
+ int msgID = MSGID_LDAPSEARCH_VLV_INVALID_DESCRIPTOR;
+ String message = getMessage(msgID);
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ return 1;
+ }
+ }
+ else if (numTokens == 4)
+ {
+ try
+ {
+ int beforeCount = Integer.parseInt(tokenizer.nextToken());
+ int afterCount = Integer.parseInt(tokenizer.nextToken());
+ int offset = Integer.parseInt(tokenizer.nextToken());
+ int contentCount = Integer.parseInt(tokenizer.nextToken());
+ searchOptions.getControls().add(
+ new LDAPControl(new VLVRequestControl(beforeCount, afterCount,
+ offset, contentCount)));
+ }
+ catch (Exception e)
+ {
+ int msgID = MSGID_LDAPSEARCH_VLV_INVALID_DESCRIPTOR;
+ String message = getMessage(msgID);
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ return 1;
+ }
+ }
+ else
+ {
+ int msgID = MSGID_LDAPSEARCH_VLV_INVALID_DESCRIPTOR;
+ String message = getMessage(msgID);
+ err.println(wrapText(message, MAX_LINE_WIDTH));
+ return 1;
+ }
+ }
+
// Set the connection options.
connectionOptions.setSASLExternal(saslExternal.isPresent());
if(saslOptions.isPresent())
--
Gitblit v1.10.0