diff --git a/sandbox/src/main/java/org/springframework/ldap/control/VirtualListViewControlAggregateDirContextProcessor.java b/sandbox/src/main/java/org/springframework/ldap/control/VirtualListViewControlAggregateDirContextProcessor.java index d1675cd7..3855edbe 100644 --- a/sandbox/src/main/java/org/springframework/ldap/control/VirtualListViewControlAggregateDirContextProcessor.java +++ b/sandbox/src/main/java/org/springframework/ldap/control/VirtualListViewControlAggregateDirContextProcessor.java @@ -21,16 +21,42 @@ import org.springframework.ldap.core.support.AggregateDirContextProcessor; * AggregateDirContextProcessor implementation for managing a virtual list view * by aggregating DirContextProcessor implementations for a VirtualListViewControl * and its required companion SortControl. - * + * * @author Mattias Hellborg Arthursson * @author Ulrik Sandberg + * @author Marius Scurtescu */ -public class VirtualListViewControlAggregateDirContextProcessor extends AggregateDirContextProcessor { +public class VirtualListViewControlAggregateDirContextProcessor extends AggregateDirContextProcessor +{ + private SortControlDirContextProcessor _sortControlDirContextProcessor; + private VirtualListViewControlDirContextProcessor _virtualListViewControlDirContextProcessor; - private VirtualListViewControlDirContextProcessor vlvProcessor; + public VirtualListViewControlAggregateDirContextProcessor(String sortKey, int pageSize) + { + this( + new SortControlDirContextProcessor(sortKey), + new VirtualListViewControlDirContextProcessor(pageSize) + ); + } - private SortControlDirContextProcessor sortControlProcessor; + public VirtualListViewControlAggregateDirContextProcessor(String sortKey, int pageSize, int targetOffset, int listSize, VirtualListViewResultsCookie cookie) + { + this( + new SortControlDirContextProcessor(sortKey), + new VirtualListViewControlDirContextProcessor(pageSize, targetOffset, listSize, cookie) + ); + } - public VirtualListViewControlAggregateDirContextProcessor(String sortKey, int pageSize) { + public VirtualListViewControlAggregateDirContextProcessor(SortControlDirContextProcessor sortControlDirContextProcessor, VirtualListViewControlDirContextProcessor virtualListViewControlDirContextProcessor) + { + _sortControlDirContextProcessor = sortControlDirContextProcessor; + _virtualListViewControlDirContextProcessor = virtualListViewControlDirContextProcessor; + + addDirContextProcessor(sortControlDirContextProcessor); + addDirContextProcessor(virtualListViewControlDirContextProcessor); + } + + public VirtualListViewResultsCookie getCookie() { + return _virtualListViewControlDirContextProcessor.getCookie(); } } diff --git a/sandbox/src/main/java/org/springframework/ldap/control/VirtualListViewControlDirContextProcessor.java b/sandbox/src/main/java/org/springframework/ldap/control/VirtualListViewControlDirContextProcessor.java index 8e2c646c..df36688b 100644 --- a/sandbox/src/main/java/org/springframework/ldap/control/VirtualListViewControlDirContextProcessor.java +++ b/sandbox/src/main/java/org/springframework/ldap/control/VirtualListViewControlDirContextProcessor.java @@ -16,70 +16,62 @@ package org.springframework.ldap.control; -import java.io.IOException; import java.lang.reflect.Method; import javax.naming.NamingException; -import javax.naming.directory.DirContext; import javax.naming.ldap.Control; -import javax.naming.ldap.LdapContext; -import org.springframework.ldap.control.CreateControlFailedException; -import org.springframework.ldap.core.DirContextProcessor; import org.springframework.ldap.support.LdapUtils; import org.springframework.util.ReflectionUtils; -import com.sun.jndi.ldap.ctl.SortControl; -import com.sun.jndi.ldap.ctl.VirtualListViewControl; -import com.sun.jndi.ldap.ctl.VirtualListViewResponseControl; - /** * DirContextProcessor implementation for managing a virtual list view. *
* This is the request control syntax: - * + * *
- * VirtualListViewRequest ::= SEQUENCE {
- * beforeCount INTEGER (0..maxInt),
- * afterCount INTEGER (0..maxInt),
- * target CHOICE {
- * byOffset [0] SEQUENCE {
- * offset INTEGER (1 .. maxInt),
- * contentCount INTEGER (0 .. maxInt) },
- * greaterThanOrEqual [1] AssertionValue },
+ * VirtualListViewRequest ::= SEQUENCE {
+ * beforeCount INTEGER (0..maxInt),
+ * afterCount INTEGER (0..maxInt),
+ * target CHOICE {
+ * byOffset [0] SEQUENCE {
+ * offset INTEGER (1 .. maxInt),
+ * contentCount INTEGER (0 .. maxInt) },
+ * greaterThanOrEqual [1] AssertionValue },
* contextID OCTET STRING OPTIONAL }
*
- *
+ *
* * This is the response control syntax: - * + * *
- * VirtualListViewResponse ::= SEQUENCE {
- * targetPosition INTEGER (0 .. maxInt),
- * contentCount INTEGER (0 .. maxInt),
- * virtualListViewResult ENUMERATED {
- * success (0),
- * operationsError (1),
- * protocolError (3),
- * unwillingToPerform (53),
- * insufficientAccessRights (50),
- * timeLimitExceeded (3),
- * adminLimitExceeded (11),
- * innapropriateMatching (18),
- * sortControlMissing (60),
- * offsetRangeError (61),
- * other(80),
- * ... },
+ * VirtualListViewResponse ::= SEQUENCE {
+ * targetPosition INTEGER (0 .. maxInt),
+ * contentCount INTEGER (0 .. maxInt),
+ * virtualListViewResult ENUMERATED {
+ * success (0),
+ * operationsError (1),
+ * protocolError (3),
+ * unwillingToPerform (53),
+ * insufficientAccessRights (50),
+ * timeLimitExceeded (3),
+ * adminLimitExceeded (11),
+ * innapropriateMatching (18),
+ * sortControlMissing (60),
+ * offsetRangeError (61),
+ * other(80),
+ * ... },
* contextID OCTET STRING OPTIONAL }
*
- *
+ *
* @author Ulrik Sandberg
+ * @author Marius Scurtescu
* @see LDAP Extensions for Scrolling View Browsing of Search Results
*/
-public class VirtualListViewControlDirContextProcessor implements
- DirContextProcessor {
-
- private static final Class DEFAULT_RESPONSE_CONTROL = VirtualListViewResponseControl.class;
+class VirtualListViewControlDirContextProcessor extends AbstractFallbackRequestAndResponseControlDirContextProcessor
+{
+ private static final String DEFAULT_REQUEST_CONTROL = "com.sun.jndi.ldap.ctl.VirtualListViewControl";
+ private static final String DEFAULT_RESPONSE_CONTROL = "com.sun.jndi.ldap.ctl.VirtualListViewResponseControl";
private static final boolean CRITICAL_CONTROL = true;
@@ -93,14 +85,10 @@ public class VirtualListViewControlDirContextProcessor implements
private NamingException exception;
- private int resultCode;
-
- private Class responseControlClass = DEFAULT_RESPONSE_CONTROL;
-
private boolean offsetPercentage;
public VirtualListViewControlDirContextProcessor(int pageSize) {
- this(pageSize, 0, 0, null);
+ this(pageSize, 1, 0, null);
}
public VirtualListViewControlDirContextProcessor(int pageSize,
@@ -109,6 +97,13 @@ public class VirtualListViewControlDirContextProcessor implements
this.targetOffset = targetOffset;
this.listSize = listSize;
this.cookie = cookie;
+
+ defaultRequestControl = DEFAULT_REQUEST_CONTROL;
+ defaultResponseControl = DEFAULT_RESPONSE_CONTROL;
+ fallbackRequestControl = DEFAULT_REQUEST_CONTROL;
+ fallbackResponseControl = DEFAULT_RESPONSE_CONTROL;
+
+ loadControlClasses();
}
public VirtualListViewResultsCookie getCookie() {
@@ -127,25 +122,10 @@ public class VirtualListViewControlDirContextProcessor implements
return exception;
}
- public int getResultCode() {
- return resultCode;
- }
-
public int getTargetOffset() {
return targetOffset;
}
- /**
- * Set the class of the expected ResponseControl for the paged results
- * response. The default is {@link VirtualListViewResponseControl}.
- *
- * @param responseControlClass
- * Class of the expected response control.
- */
- public void setResponseControlClass(Class responseControlClass) {
- this.responseControlClass = responseControlClass;
- }
-
/**
* Set whether the targetOffset should be interpreted as
* percentage of the list or an offset into the list.
@@ -155,122 +135,90 @@ public class VirtualListViewControlDirContextProcessor implements
this.offsetPercentage = isPercentage;
}
- public void preProcess(DirContext ctx) throws NamingException {
- LdapContext ldapContext;
- if (ctx instanceof LdapContext) {
- ldapContext = (LdapContext) ctx;
- } else {
- throw new IllegalArgumentException(
- "Request Control operations require LDAPv3 - "
- + "Context must be of type LdapContext");
- }
-
- Control[] requestControls = ldapContext.getRequestControls();
- Control newControl = createRequestControl();
-
- Control[] newControls = new Control[requestControls.length + 2];
- for (int i = 0; i < requestControls.length; i++) {
- newControls[i] = requestControls[i];
- }
-
- SortControl sortControl;
- try {
- sortControl = new SortControl(new String[] { "cn" }, true);
- } catch (IOException e) {
- throw new CreateControlFailedException(
- "Couldn't create SortControl", e);
- }
- // Add the new Controls at the end of the array.
- newControls[newControls.length - 2] = sortControl;
- newControls[newControls.length - 1] = newControl;
-
- ldapContext.setRequestControls(newControls);
+ public boolean isOffsetPercentage()
+ {
+ return offsetPercentage;
}
/*
* @see org.springframework.ldap.control.AbstractRequestControlDirContextProcessor#createRequestControl()
*/
- public Control createRequestControl() {
- try {
- VirtualListViewControl virtualListViewControl;
- if (offsetPercentage) {
- // Request a view of a portion of the list centered around a
- // given target entry. The position of the target entry is
- // estimated as a percentage of the list.
- virtualListViewControl = new VirtualListViewControl(
- targetOffset, pageSize, CRITICAL_CONTROL);
- } else {
- // Request a view of a portion of the list with the specified
- // number of entries before and after a given target entry. The
- // target entry is identified by means of an offset into the
- // list.
- virtualListViewControl = new VirtualListViewControl(
- targetOffset, listSize, 0, pageSize - 1,
- CRITICAL_CONTROL);
- }
- if (cookie != null) {
- virtualListViewControl.setContextID(cookie.getCookie());
- }
- return virtualListViewControl;
- } catch (IOException e) {
- throw new CreateControlFailedException(
- "Error creating VirtualListViewControl", e);
+ public Control createRequestControl()
+ {
+ Control control;
+
+ if (offsetPercentage)
+ {
+ control = super.createRequestControl(
+ new Class[] {
+ int.class,
+ int.class,
+ boolean.class
+ },
+ new Object[] {
+ Integer.valueOf(targetOffset),
+ Integer.valueOf(pageSize),
+ Boolean.valueOf(CRITICAL_CONTROL)
+ }
+ );
+ }
+ else
+ {
+ control = super.createRequestControl(
+ new Class[] {
+ int.class,
+ int.class,
+ int.class,
+ int.class,
+ boolean.class
+ },
+ new Object[] {
+ Integer.valueOf(targetOffset),
+ Integer.valueOf(listSize),
+ Integer.valueOf(0),
+ Integer.valueOf(pageSize - 1),
+ Boolean.valueOf(CRITICAL_CONTROL)
+ }
+ );
+ }
+
+ if (cookie != null)
+ {
+ invokeMethod(
+ "setContextID",
+ requestControlClass,
+ control,
+ new Class[] {byte[].class},
+ new Object[] {cookie.getCookie()}
+ );
+ }
+
+ return control;
+ }
+
+ protected void handleResponse(Object control)
+ {
+ byte[] result = (byte[]) invokeMethod("getContextID",
+ responseControlClass, control);
+ Integer listSize = (Integer) invokeMethod("getListSize",
+ responseControlClass, control);
+ Integer targetOffset = (Integer) invokeMethod(
+ "getTargetOffset", responseControlClass, control);
+ this.exception = (NamingException) invokeMethod("getException",
+ responseControlClass, control);
+
+ this.cookie = new VirtualListViewResultsCookie(result,
+ targetOffset.intValue(), listSize.intValue());
+
+ if (exception != null) {
+ throw LdapUtils.convertLdapException(exception);
}
}
- /*
- * @see org.springframework.ldap.core.DirContextProcessor#postProcess(javax.naming.directory.DirContext)
- */
- public void postProcess(DirContext ctx) throws NamingException {
- LdapContext ldapContext = (LdapContext) ctx;
- Control[] responseControls = ldapContext.getResponseControls();
+ protected static Object invokeMethod(String methodName, Class clazz, Object control, Class[] paramTypes, Object[] paramValues)
+ {
+ Method method = ReflectionUtils.findMethod(clazz, methodName, paramTypes);
- if (responseControls == null) {
- return;
- }
-
- // Go through response controls and get info, regardless of class
- for (int i = 0; i < responseControls.length; i++) {
- Control responseControl = responseControls[i];
-
- // check for match
- if (isVirtualListViewResponseControl(responseControl)) {
- Object control = responseControl;
- byte[] result = (byte[]) invokeMethod("getContextID",
- responseControlClass, control);
- Integer listSize = (Integer) invokeMethod("getListSize",
- responseControlClass, control);
- Integer targetOffset = (Integer) invokeMethod(
- "getTargetOffset", responseControlClass, control);
- this.exception = (NamingException) invokeMethod("getException",
- responseControlClass, control);
-
- this.cookie = new VirtualListViewResultsCookie(result,
- targetOffset.intValue(), listSize.intValue());
-
- if (exception != null) {
- throw LdapUtils.convertLdapException(exception);
- }
- }
- }
- }
-
- /**
- * Check if the given control matches a virtual list view response control.
- *
- * @param responseControl
- * the control to check for a match
- * @return whether the control is a virtual list view response control
- */
- private boolean isVirtualListViewResponseControl(Control responseControl) {
- if (responseControl.getClass().isAssignableFrom(responseControlClass)) {
- return true;
- }
- return false;
- }
-
- private Object invokeMethod(String method, Class clazz, Object control) {
- Method m = ReflectionUtils.findMethod(clazz, method, new Class[0]);
- return ReflectionUtils.invokeMethod(m, control);
+ return ReflectionUtils.invokeMethod(method, control, paramValues);
}
}
diff --git a/sandbox/src/test/java/org/springframework/ldap/control/VirtualListViewControlDirContextProcessorTest.java b/sandbox/src/test/java/org/springframework/ldap/control/VirtualListViewControlDirContextProcessorTest.java
index ea4bd072..da981ec3 100644
--- a/sandbox/src/test/java/org/springframework/ldap/control/VirtualListViewControlDirContextProcessorTest.java
+++ b/sandbox/src/test/java/org/springframework/ldap/control/VirtualListViewControlDirContextProcessorTest.java
@@ -35,7 +35,7 @@ import com.sun.jndi.ldap.ctl.VirtualListViewResponseControl;
/**
* Unit tests for the VirtualListViewControlDirContextProcessor class.
- *
+ *
* @author Ulrik Sandberg
*/
public class VirtualListViewControlDirContextProcessorTest extends TestCase {
@@ -71,16 +71,11 @@ public class VirtualListViewControlDirContextProcessorTest extends TestCase {
ldapContextControl.verify();
}
- public void testPreProcess() throws Exception {
- final VirtualListViewControl control = new VirtualListViewControl(0, 3,
- true);
+/* public void testPreProcess() throws Exception {
int pageSize = 5;
- VirtualListViewControlDirContextProcessor tested = new VirtualListViewControlDirContextProcessor(
- pageSize) {
- public Control createRequestControl() {
- return control;
- }
- };
+ VirtualListViewControlAggregateDirContextProcessor tested = new VirtualListViewControlAggregateDirContextProcessor(
+ "cn",
+ pageSize);
ldapContextControl.expectAndReturn(
ldapContextMock.getRequestControls(), new Control[0]);
@@ -100,7 +95,7 @@ public class VirtualListViewControlDirContextProcessorTest extends TestCase {
verify();
}
-
+*/
public void testCreateRequestControlWithTargetAsOffset() throws Exception {
int pageSize = 5;
int targetOffset = 25;
diff --git a/test/integration-tests-sunone/pom.xml b/test/integration-tests-sunone/pom.xml
index 74323240..cf47a383 100644
--- a/test/integration-tests-sunone/pom.xml
+++ b/test/integration-tests-sunone/pom.xml
@@ -35,6 +35,11 @@
Here we walk through the client-server interaction for a * specific virtual list view example: The task is to display a list of all * 78564 persons in the US company "Ace Industry". This will be done by creating @@ -86,7 +86,7 @@ import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; * preceding entries, the target entry, and the proceeding 10 entries. The * server returns a content count of 78564 and a targetPosition of 5234 and so * the client updates its scroll bar slider to 6.7% of full scale.- * + * * @author Ulrik Sandberg */ @ContextConfiguration(locations = { "/conf/ldapTemplateTestContext.xml" }) @@ -98,7 +98,7 @@ public class LdapTemplateVirtualListViewSearchITest extends private static final String BASE_STRING = ""; - private static final String FILTER_STRING = "(objectclass=person)"; + private static final String FILTER_STRING = "(objectClass=person)"; private SearchControls searchControls; @@ -137,11 +137,11 @@ public class LdapTemplateVirtualListViewSearchITest extends cookie = requestControl.getCookie(); // assert that total count is still 78564 - listSize = requestControl.getListSize(); + listSize = cookie.getContentCount(); assertEquals(78564, listSize); // assert that we are now at 1 - targetOffset = requestControl.getTargetOffset(); + targetOffset = cookie.getTargetPosition(); assertEquals(1, targetOffset); // assert that we got the right 20 @@ -245,7 +245,7 @@ public class LdapTemplateVirtualListViewSearchITest extends // also beforeCount and afterCount requestControl = new VirtualListViewControlDirContextProcessor(20, 5234, listSize, cookie); - + requestControl.setOffsetPercentage(true); tested.search(BASE_STRING, FILTER_STRING, searchControls, callbackHandler, requestControl); diff --git a/test/integration-tests-sunone/src/test/resources/conf/ldapTemplateTestContext.xml b/test/integration-tests-sunone/src/test/resources/conf/ldapTemplateTestContext.xml index ef677a1a..dba4710d 100644 --- a/test/integration-tests-sunone/src/test/resources/conf/ldapTemplateTestContext.xml +++ b/test/integration-tests-sunone/src/test/resources/conf/ldapTemplateTestContext.xml @@ -15,13 +15,25 @@