diff --git a/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java b/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java index abb114f2..636b3e27 100644 --- a/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java +++ b/core/src/main/java/org/springframework/ldap/core/LdapTemplate.java @@ -62,8 +62,6 @@ public class LdapTemplate implements LdapOperations, InitializingBean { private static final Log log = LogFactory.getLog(LdapTemplate.class); - private static final int DEFAULT_SEARCH_SCOPE = SearchControls.SUBTREE_SCOPE; - private static final boolean DONT_RETURN_OBJ_FLAG = false; private static final boolean RETURN_OBJ_FLAG = true; @@ -76,6 +74,12 @@ public class LdapTemplate implements LdapOperations, InitializingBean { private boolean ignoreNameNotFoundException = false; + private int defaultSearchScope = SearchControls.SUBTREE_SCOPE; + + private int defaultTimeLimit = 0; + + private int defaultCountLimit = 0; + /** * Constructor for bean usage. */ @@ -149,12 +153,47 @@ public class LdapTemplate implements LdapOperations, InitializingBean { this.ignorePartialResultException = ignore; } - /* - * @see - * org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, - * java.lang.String, int, boolean, - * org.springframework.ldap.core.NameClassPairCallbackHandler) - */ + /** + * Set the default scope to be used in searches if not explicitly specified. + * Default is {@link SearchControls.SUBTREE_SCOPE}. + * + * @param defaultSearchScope the default search scope to use in searches. + * One of {@link SearchControls.OBJECT_SCOPE}, + * {@link SearchControls.ONELEVEL_SCOPE}, + * or {@link SearchControls.SUBTREE_SCOPE} + * @since 2.0 + */ + public void setDefaultSearchScope(int defaultSearchScope) { + this.defaultSearchScope = defaultSearchScope; + } + + /** + * Set the default time limit be used in searches if not explicitly specified. + * Default is 0, indicating no time limit. + * + * @param defaultTimeLimit the default time limit to use in searches. + * @since 2.0 + */ + public void setDefaultTimeLimit(int defaultTimeLimit) { + this.defaultTimeLimit = defaultTimeLimit; + } + + /** + * Set the default count limit be used in searches if not explicitly specified. + * Default is 0, indicating no count limit. + * + * @param defaultCountLimit the default count limit to use in searches. + */ + public void setDefaultCountLimit(int defaultCountLimit) { + this.defaultCountLimit = defaultCountLimit; + } + + /* + * @see + * org.springframework.ldap.core.LdapOperations#search(javax.naming.Name, + * java.lang.String, int, boolean, + * org.springframework.ldap.core.NameClassPairCallbackHandler) + */ public void search(Name base, String filter, int searchScope, boolean returningObjFlag, NameClassPairCallbackHandler handler) { @@ -369,7 +408,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { */ public void search(Name base, String filter, NameClassPairCallbackHandler handler) { - SearchControls controls = getDefaultSearchControls(DEFAULT_SEARCH_SCOPE, DONT_RETURN_OBJ_FLAG, ALL_ATTRIBUTES); + SearchControls controls = getDefaultSearchControls(defaultSearchScope, DONT_RETURN_OBJ_FLAG, ALL_ATTRIBUTES); if (handler instanceof ContextMapperCallbackHandler) { assureReturnObjFlagSet(controls); } @@ -384,7 +423,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { */ public void search(String base, String filter, NameClassPairCallbackHandler handler) { - SearchControls controls = getDefaultSearchControls(DEFAULT_SEARCH_SCOPE, DONT_RETURN_OBJ_FLAG, ALL_ATTRIBUTES); + SearchControls controls = getDefaultSearchControls(defaultSearchScope, DONT_RETURN_OBJ_FLAG, ALL_ATTRIBUTES); if (handler instanceof ContextMapperCallbackHandler) { assureReturnObjFlagSet(controls); } @@ -438,7 +477,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { */ public List search(Name base, String filter, AttributesMapper mapper) { - return search(base, filter, DEFAULT_SEARCH_SCOPE, mapper); + return search(base, filter, defaultSearchScope, mapper); } /* @@ -448,7 +487,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { */ public List search(String base, String filter, AttributesMapper mapper) { - return search(base, filter, DEFAULT_SEARCH_SCOPE, mapper); + return search(base, filter, defaultSearchScope, mapper); } /* @@ -500,7 +539,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { */ public List search(Name base, String filter, ContextMapper mapper) { - return search(base, filter, DEFAULT_SEARCH_SCOPE, mapper); + return search(base, filter, defaultSearchScope, mapper); } /* @@ -510,7 +549,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean { */ public List search(String base, String filter, ContextMapper mapper) { - return search(base, filter, DEFAULT_SEARCH_SCOPE, mapper); + return search(base, filter, defaultSearchScope, mapper); } /* @@ -1214,9 +1253,10 @@ public class LdapTemplate implements LdapOperations, InitializingBean { } private SearchControls getDefaultSearchControls(int searchScope, boolean returningObjFlag, String[] attrs) { - SearchControls controls = new SearchControls(); controls.setSearchScope(searchScope); + controls.setTimeLimit(defaultTimeLimit); + controls.setCountLimit(defaultCountLimit); controls.setReturningObjFlag(returningObjFlag); controls.setReturningAttributes(attrs); return controls; diff --git a/core/src/test/java/org/springframework/ldap/core/LdapTemplateTest.java b/core/src/test/java/org/springframework/ldap/core/LdapTemplateTest.java index fe49bfb1..aa47d996 100644 --- a/core/src/test/java/org/springframework/ldap/core/LdapTemplateTest.java +++ b/core/src/test/java/org/springframework/ldap/core/LdapTemplateTest.java @@ -453,6 +453,38 @@ public class LdapTemplateTest { assertSame(expectedResult, list.get(0)); } + @Test + public void verifyThatDefaultSearchControlParametersAreAutomaticallyAppliedInSearch() throws Exception { + tested.setDefaultSearchScope(SearchControls.ONELEVEL_SCOPE); + tested.setDefaultCountLimit(5000); + tested.setDefaultTimeLimit(500); + + expectGetReadOnlyContext(); + + SearchControls controls = new SearchControls(); + controls.setReturningObjFlag(false); + controls.setCountLimit(5000); + controls.setTimeLimit(500); + controls.setSearchScope(SearchControls.ONELEVEL_SCOPE); + + BasicAttributes expectedAttributes = new BasicAttributes(); + SearchResult searchResult = new SearchResult("", null, expectedAttributes); + + singleSearchResult(controls, searchResult); + + Object expectedResult = new Object(); + when(attributesMapperMock.mapFromAttributes(expectedAttributes)).thenReturn(expectedResult); + + List list = tested.search(nameMock, "(ou=somevalue)", attributesMapperMock); + + verify(namingEnumerationMock).close(); + verify(dirContextMock).close(); + + assertNotNull(list); + assertEquals(1, list.size()); + assertSame(expectedResult, list.get(0)); + } + @Test public void testSearch_AttributesMapper() throws Exception { expectGetReadOnlyContext(); @@ -1597,7 +1629,8 @@ public class LdapTemplateTest { return controls.getSearchScope() == s1.getSearchScope() && controls.getReturningObjFlag() == s1.getReturningObjFlag() - && controls.getDerefLinkFlag() == s1.getDerefLinkFlag() && controls.getCountLimit() == s1.getCountLimit() + && controls.getDerefLinkFlag() == s1.getDerefLinkFlag() + && controls.getCountLimit() == s1.getCountLimit() && controls.getTimeLimit() == s1.getTimeLimit() && controls.getReturningAttributes() == s1.getReturningAttributes(); }