From d6a18c0ea456c2f132c2301b37c80fe7e3e3a276 Mon Sep 17 00:00:00 2001
From: coulbeck <coulbeck@localhost>
Date: Thu, 12 Oct 2006 16:20:20 +0000
Subject: [PATCH] Fixes for the following issues, reviewed by neil_a_wilson.
---
opends/tests/unit-tests-testng/src/server/org/opends/server/core/SearchOperationTestCase.java | 189 +++++++++++++++++++-
opends/src/server/org/opends/server/types/Attribute.java | 39 +++
opends/src/server/org/opends/server/types/Entry.java | 141 +++++++++++++-
opends/src/server/org/opends/server/core/SearchOperation.java | 168 ++++--------------
4 files changed, 373 insertions(+), 164 deletions(-)
diff --git a/opends/src/server/org/opends/server/core/SearchOperation.java b/opends/src/server/org/opends/server/core/SearchOperation.java
index 16620e2..d0feac0 100644
--- a/opends/src/server/org/opends/server/core/SearchOperation.java
+++ b/opends/src/server/org/opends/server/core/SearchOperation.java
@@ -932,14 +932,6 @@
List<Attribute> ocList = new ArrayList<Attribute>(1);
ocList.add(new Attribute(ocType));
entryToReturn.putAttribute(ocType, ocList);
-
- // Next, iterate through all the user attributes and include them.
- for (AttributeType t : entry.getUserAttributes().keySet())
- {
- List<Attribute> attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(t));
- entryToReturn.putAttribute(t, attrList);
- }
}
else
{
@@ -954,13 +946,14 @@
// We cannot get this exception because the object classes have
// already been validated in the entry they came from.
}
+ }
-
- // Next iterate through all the user attributes and include them.
- for (AttributeType t : entry.getUserAttributes().keySet())
- {
- entryToReturn.putAttribute(t, entry.duplicateUserAttribute(t));
- }
+ // Next iterate through all the user attributes and include them.
+ for (AttributeType t : entry.getUserAttributes().keySet())
+ {
+ List<Attribute> attrList =
+ entry.duplicateUserAttribute(t, null, typesOnly);
+ entryToReturn.putAttribute(t, attrList);
}
continue;
@@ -971,17 +964,9 @@
// attributes should be returned.
for (AttributeType t : entry.getOperationalAttributes().keySet())
{
- if (typesOnly)
- {
- List<Attribute> attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(t));
- entryToReturn.putAttribute(t, attrList);
- }
- else
- {
- entryToReturn.putAttribute(t,
- entry.duplicateOperationalAttribute(t));
- }
+ List<Attribute> attrList =
+ entry.duplicateOperationalAttribute(t, null, typesOnly);
+ entryToReturn.putAttribute(t, attrList);
}
continue;
@@ -1020,53 +1005,15 @@
{
if (t.hasNameOrOID(lowerName))
{
- if ((options == null) || options.isEmpty())
+ List<Attribute> attrList =
+ entry.duplicateUserAttribute(t, options, typesOnly);
+ if (attrList != null)
{
- if (typesOnly)
- {
- List<Attribute> attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(t));
- entryToReturn.putAttribute(t, attrList);
- }
- else
- {
- entryToReturn.putAttribute(t,
- entry.duplicateUserAttribute(t));
- }
+ entryToReturn.putAttribute(t, attrList);
added = true;
break;
}
- else
- {
- List<Attribute> attrList = entry.duplicateUserAttribute(t);
- List<Attribute> includeAttrs =
- new ArrayList<Attribute>(attrList.size());
- for (Attribute a : attrList)
- {
- if (a.hasOptions(options))
- {
- includeAttrs.add(a);
- }
- }
-
- if (! includeAttrs.isEmpty())
- {
- if (typesOnly)
- {
- attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(t));
- entryToReturn.putAttribute(t, attrList);
- }
- else
- {
- entryToReturn.putAttribute(t, includeAttrs);
- }
-
- added = true;
- break;
- }
- }
}
}
@@ -1079,87 +1026,48 @@
{
if (t.hasNameOrOID(lowerName))
{
- if ((options == null) || options.isEmpty())
+ List<Attribute> attrList =
+ entry.duplicateOperationalAttribute(t, options, typesOnly);
+ if (attrList != null)
{
- if (typesOnly)
- {
- List<Attribute> attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(t));
- entryToReturn.putAttribute(t, attrList);
- }
- else
- {
- entryToReturn.putAttribute(t,
- entry.duplicateOperationalAttribute(t));
- }
+ entryToReturn.putAttribute(t, attrList);
- added = true;
break;
}
- else
- {
- List<Attribute> attrList =
- entry.duplicateOperationalAttribute(t);
- List<Attribute> includeAttrs =
- new ArrayList<Attribute>(attrList.size());
- for (Attribute a : attrList)
- {
- if (a.hasOptions(options))
- {
- includeAttrs.add(a);
- }
- }
-
- if (! includeAttrs.isEmpty())
- {
- if (typesOnly)
- {
- attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(t));
- entryToReturn.putAttribute(t, attrList);
- }
- else
- {
- entryToReturn.putAttribute(t, includeAttrs);
- }
-
- added = true;
- break;
- }
- }
}
}
}
else
{
- if (attrType.isObjectClassType() && !typesOnly)
- {
- Attribute ocAttr = entry.getObjectClassAttribute();
- try
+ if (attrType.isObjectClassType()) {
+ if (typesOnly)
{
- entryToReturn.setObjectClasses(ocAttr.getValues());
+ AttributeType ocType =
+ DirectoryServer.getObjectClassAttributeType();
+ List<Attribute> ocList = new ArrayList<Attribute>(1);
+ ocList.add(new Attribute(ocType));
+ entryToReturn.putAttribute(ocType, ocList);
}
- catch (DirectoryException e)
+ else
{
- // We cannot get this exception because the object classes have
- // already been validated in the entry they came from.
+ List<Attribute> attrList = new ArrayList<Attribute>(1);
+ attrList.add(entry.getObjectClassAttribute());
+ entryToReturn.putAttribute(attrType, attrList);
}
}
else
{
- List<Attribute> attrList = entry.getAttribute(attrType, options);
+ List<Attribute> attrList =
+ entry.duplicateOperationalAttribute(attrType, options,
+ typesOnly);
+ if (attrList == null)
+ {
+ attrList = entry.duplicateUserAttribute(attrType, options,
+ typesOnly);
+ }
if (attrList != null)
{
- if (typesOnly)
- {
- attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(attrType));
- entryToReturn.putAttribute(attrType, attrList);
- }
- else
- {
- entryToReturn.putAttribute(attrType, attrList);
- }
+ entryToReturn.putAttribute(attrType, attrList);
}
}
}
diff --git a/opends/src/server/org/opends/server/types/Attribute.java b/opends/src/server/org/opends/server/types/Attribute.java
index e7f0801..fec73c5 100644
--- a/opends/src/server/org/opends/server/types/Attribute.java
+++ b/opends/src/server/org/opends/server/types/Attribute.java
@@ -836,6 +836,25 @@
{
assert debugEnter(CLASS_NAME, "duplicate");
+ return duplicate(false);
+ }
+
+
+ /**
+ * Creates a duplicate of this attribute that can be modified
+ * without impacting this attribute.
+ *
+ * @param omitValues <CODE>true</CODE> if the values should be
+ * omitted.
+ *
+ * @return A duplicate of this attribute that can be modified
+ * without impacting this attribute.
+ */
+ public Attribute duplicate(boolean omitValues)
+ {
+ assert debugEnter(CLASS_NAME, "duplicate",
+ String.valueOf(omitValues));
+
LinkedHashSet<String> optionsCopy =
new LinkedHashSet<String>(options.size());
for (String s : options)
@@ -843,19 +862,25 @@
optionsCopy.add(s);
}
- LinkedHashSet<AttributeValue> valuesCopy =
- new LinkedHashSet<AttributeValue>(values.size());
- for (AttributeValue v : values)
+ if (omitValues)
{
- valuesCopy.add(v);
+ return new Attribute(attributeType, name, optionsCopy, null);
}
+ else
+ {
+ LinkedHashSet<AttributeValue> valuesCopy =
+ new LinkedHashSet<AttributeValue>(values.size());
+ for (AttributeValue v : values)
+ {
+ valuesCopy.add(v);
+ }
- return new Attribute(attributeType, name, optionsCopy,
- valuesCopy);
+ return new Attribute(attributeType, name, optionsCopy,
+ valuesCopy);
+ }
}
-
/**
* Indicates whether the provided object is an attribute that is
* equal to this attribute. It will be considered equal if the
diff --git a/opends/src/server/org/opends/server/types/Entry.java b/opends/src/server/org/opends/server/types/Entry.java
index b33b3f1..f2d9f54 100644
--- a/opends/src/server/org/opends/server/types/Entry.java
+++ b/opends/src/server/org/opends/server/types/Entry.java
@@ -1146,6 +1146,122 @@
/**
+ * Makes a copy of attributes matching the specified options.
+ *
+ * @param attrList The attributes to be copied.
+ * @param options The set of attribute options to include in
+ * matching elements.
+ * @param omitValues <CODE>true</CODE> if the values are to be
+ * omitted.
+ *
+ * @return A copy of the attributes matching the specified options,
+ * or <CODE>null</CODE> if there is no such attribute with
+ * the specified set of options.
+ */
+ private static List<Attribute> duplicateAttribute(
+ List<Attribute> attrList,
+ Set<String> options,
+ boolean omitValues)
+ {
+ assert debugEnter(CLASS_NAME, "duplicateAttribute",
+ String.valueOf(attrList),
+ String.valueOf(options),
+ String.valueOf(omitValues));
+
+ if (attrList == null)
+ {
+ return null;
+ }
+
+ ArrayList<Attribute> duplicateList =
+ new ArrayList<Attribute>(attrList.size());
+ for (Attribute a : attrList)
+ {
+ if (a.hasOptions(options))
+ {
+ duplicateList.add(a.duplicate(omitValues));
+ }
+ }
+
+ if (duplicateList.isEmpty())
+ {
+ return null;
+ }
+ else
+ {
+ return duplicateList;
+ }
+ }
+
+
+
+ /**
+ * Retrieves a copy of the requested user attribute element(s) for
+ * the specified attribute type. The list returned may include
+ * multiple elements if the same attribute exists in the entry
+ * multiple times with different sets of options.
+ *
+ * @param attributeType The attribute type to retrieve.
+ * @param options The set of attribute options to include in
+ * matching elements.
+ * @param omitValues <CODE>true</CODE> if the values are to be
+ * omitted.
+ *
+ * @return A copy of the requested attribute element(s) for the
+ * specified attribute type, or <CODE>null</CODE> if there
+ * is no such user attribute with the specified set of
+ * options.
+ */
+ public List<Attribute> duplicateUserAttribute(
+ AttributeType attributeType,
+ Set<String> options,
+ boolean omitValues)
+ {
+ assert debugEnter(CLASS_NAME, "duplicateUserAttribute",
+ String.valueOf(attributeType),
+ String.valueOf(options),
+ String.valueOf(omitValues));
+
+ List<Attribute> currentList = userAttributes.get(attributeType);
+ return duplicateAttribute(currentList, options, omitValues);
+ }
+
+
+
+ /**
+ * Retrieves a copy of the requested operational attribute
+ * element(s) for the specified attribute type. The list returned
+ * may include multiple elements if the same attribute exists in
+ * the entry multiple times with different sets of options.
+ *
+ * @param attributeType The attribute type to retrieve.
+ * @param options The set of attribute options to include in
+ * matching elements.
+ * @param omitValues <CODE>true</CODE> if the values are to be
+ * omitted.
+ *
+ * @return A copy of the requested attribute element(s) for the
+ * specified attribute type, or <CODE>null</CODE> if there
+ * is no such user attribute with the specified set of
+ * options.
+ */
+ public List<Attribute> duplicateOperationalAttribute(
+ AttributeType attributeType,
+ Set<String> options,
+ boolean omitValues)
+ {
+ assert debugEnter(CLASS_NAME, "duplicateOperationalAttribute",
+ String.valueOf(attributeType),
+ String.valueOf(options),
+ String.valueOf(omitValues));
+
+ List<Attribute> currentList =
+ operationalAttributes.get(attributeType);
+ return duplicateAttribute(currentList, options, omitValues);
+ }
+
+
+ /**
* Indicates whether this entry contains the specified operational
* attribute.
*
@@ -2660,12 +2776,12 @@
HashMap<AttributeType,List<Attribute>> userAttrsCopy =
new HashMap<AttributeType,List<Attribute>>(
userAttributes.size());
- deepCopy(userAttributes, userAttrsCopy);
+ deepCopy(userAttributes, userAttrsCopy, false);
HashMap<AttributeType,List<Attribute>> operationalAttrsCopy =
new HashMap<AttributeType,List<Attribute>>(
operationalAttributes.size());
- deepCopy(operationalAttributes, operationalAttrsCopy);
+ deepCopy(operationalAttributes, operationalAttrsCopy, false);
return new Entry(dnCopy, objectClassesCopy, userAttrsCopy,
operationalAttrsCopy);
@@ -2715,19 +2831,9 @@
ArrayList<Attribute> ocList = new ArrayList<Attribute>(1);
ocList.add(new Attribute(ocType));
userAttrsCopy.put(ocType, ocList);
-
-
- for (AttributeType t : userAttributes.keySet())
- {
- ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
- attrList.add(new Attribute(t));
- userAttrsCopy.put(t, attrList);
- }
}
- else
- {
- deepCopy(userAttributes, userAttrsCopy);
- }
+
+ deepCopy(userAttributes, userAttrsCopy, typesOnly);
HashMap<AttributeType,List<Attribute>> operationalAttrsCopy =
new HashMap<AttributeType,List<Attribute>>(0);
@@ -2747,9 +2853,12 @@
* information.
* @param target The target map into which to place the copied
* information.
+ * @param omitValues <CODE>true</CODE> if the values should be
+ * omitted.
*/
private void deepCopy(Map<AttributeType,List<Attribute>> source,
- Map<AttributeType,List<Attribute>> target)
+ Map<AttributeType,List<Attribute>> target,
+ boolean omitValues)
{
for (AttributeType t : source.keySet())
{
@@ -2759,7 +2868,7 @@
for (Attribute a : sourceList)
{
- targetList.add(a.duplicate());
+ targetList.add(a.duplicate(omitValues));
}
target.put(t, targetList);
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/SearchOperationTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/SearchOperationTestCase.java
index dab723b..abae8a5 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/core/SearchOperationTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/core/SearchOperationTestCase.java
@@ -36,6 +36,8 @@
import org.opends.server.protocols.ldap.*;
import org.opends.server.types.*;
import org.opends.server.TestCaseUtils;
+import org.opends.server.controls.MatchedValuesFilter;
+import org.opends.server.controls.MatchedValuesControl;
import org.opends.server.plugins.InvocationCounterPlugin;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -181,7 +183,8 @@
}
private SearchResultEntryProtocolOp searchExternalForSingleEntry(
- SearchRequestProtocolOp searchRequest)
+ SearchRequestProtocolOp searchRequest,
+ ArrayList<LDAPControl> controls)
throws IOException, LDAPException, ASN1Exception, InterruptedException
{
// Establish a connection to the server.
@@ -197,7 +200,7 @@
InvocationCounterPlugin.resetAllCounters();
LDAPMessage message;
- message = new LDAPMessage(2, searchRequest);
+ message = new LDAPMessage(2, searchRequest, controls);
w.writeElement(message.encode());
message = LDAPMessage.decode(r.readElement().decodeAsSequence());
@@ -297,7 +300,8 @@
}
@Test
- public void testSearchInternalAllUserAttributesTypesOnly() throws Exception
+ public void testSearchInternalUnspecifiedAttributesOmitValues()
+ throws Exception
{
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
@@ -467,7 +471,7 @@
LDAPFilter.decode("(objectclass=inetorgperson)"),
null);
SearchResultEntryProtocolOp searchResultEntry =
- searchExternalForSingleEntry(searchRequest);
+ searchExternalForSingleEntry(searchRequest, null);
assertEquals(searchResultEntry.getAttributes().size(), ldapAttrCount);
}
@@ -487,12 +491,36 @@
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes);
SearchResultEntryProtocolOp searchResultEntry =
- searchExternalForSingleEntry(searchRequest);
+ searchExternalForSingleEntry(searchRequest, null);
assertEquals(searchResultEntry.getAttributes().size(), ldapAttrCount);
}
@Test
- public void testSearchExternalAllUserAttributesTypesOnly() throws Exception
+ public void testSearchExternalUnspecifiedAttributesOmitValues()
+ throws Exception
+ {
+ SearchRequestProtocolOp searchRequest =
+ new SearchRequestProtocolOp(
+ new ASN1OctetString("o=test"),
+ SearchScope.WHOLE_SUBTREE,
+ DereferencePolicy.NEVER_DEREF_ALIASES,
+ Integer.MAX_VALUE,
+ Integer.MAX_VALUE,
+ true,
+ LDAPFilter.decode("(objectclass=inetorgperson)"),
+ null);
+ SearchResultEntryProtocolOp searchResultEntry =
+ searchExternalForSingleEntry(searchRequest, null);
+ // The attributes will include the objectclass type.
+ assertEquals(searchResultEntry.getAttributes().size(), ldapAttrCount);
+ for (LDAPAttribute a : searchResultEntry.getAttributes())
+ {
+ assertEquals(a.getValues().size(), 0);
+ }
+ }
+
+ @Test
+ public void testSearchExternalAllUserAttributesOmitValues() throws Exception
{
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
attributes.add("*");
@@ -507,10 +535,13 @@
LDAPFilter.decode("(objectclass=inetorgperson)"),
attributes);
SearchResultEntryProtocolOp searchResultEntry =
- searchExternalForSingleEntry(searchRequest);
+ searchExternalForSingleEntry(searchRequest, null);
// The attributes will include the objectclass type.
- assertEquals(searchResultEntry.getAttributes().size(),
- entry.getUserAttributes().size() + 1);
+ assertEquals(searchResultEntry.getAttributes().size(), ldapAttrCount);
+ for (LDAPAttribute a : searchResultEntry.getAttributes())
+ {
+ assertEquals(a.getValues().size(), 0);
+ }
}
@Test
@@ -530,7 +561,7 @@
attributes);
SearchResultEntryProtocolOp searchResultEntry =
- searchExternalForSingleEntry(searchRequest);
+ searchExternalForSingleEntry(searchRequest, null);
assertEquals(searchResultEntry.getAttributes().size(), 1);
assertEquals(searchResultEntry.getAttributes().
@@ -538,6 +569,31 @@
}
@Test
+ public void testSearchExternalObjectClassAttributeOmitValues()
+ throws Exception
+ {
+ LinkedHashSet<String> attributes = new LinkedHashSet<String>();
+ attributes.add("objectclass");
+ SearchRequestProtocolOp searchRequest =
+ new SearchRequestProtocolOp(
+ new ASN1OctetString("o=test"),
+ SearchScope.WHOLE_SUBTREE,
+ DereferencePolicy.NEVER_DEREF_ALIASES,
+ Integer.MAX_VALUE,
+ Integer.MAX_VALUE,
+ true,
+ LDAPFilter.decode("(objectclass=inetorgperson)"),
+ attributes);
+
+ SearchResultEntryProtocolOp searchResultEntry =
+ searchExternalForSingleEntry(searchRequest, null);
+
+ assertEquals(searchResultEntry.getAttributes().size(), 1);
+ assertEquals(searchResultEntry.getAttributes().
+ getFirst().getValues().size(), 0);
+ }
+
+ @Test
public void testSearchExternalSelectedAttributes() throws Exception
{
LinkedHashSet<String> attributes = new LinkedHashSet<String>();
@@ -555,8 +611,119 @@
attributes);
SearchResultEntryProtocolOp searchResultEntry =
- searchExternalForSingleEntry(searchRequest);
+ searchExternalForSingleEntry(searchRequest, null);
assertEquals(searchResultEntry.getAttributes().size(), 2);
}
+
+ @Test
+ public void testSearchExternalAttributeWithSubtypes() throws Exception
+ {
+ LinkedHashSet<String> attributes = new LinkedHashSet<String>();
+ attributes.add("title");
+ SearchRequestProtocolOp searchRequest =
+ new SearchRequestProtocolOp(
+ new ASN1OctetString("o=test"),
+ SearchScope.WHOLE_SUBTREE,
+ DereferencePolicy.NEVER_DEREF_ALIASES,
+ Integer.MAX_VALUE,
+ Integer.MAX_VALUE,
+ false,
+ LDAPFilter.decode("(objectclass=inetorgperson)"),
+ attributes);
+
+ SearchResultEntryProtocolOp searchResultEntry =
+ searchExternalForSingleEntry(searchRequest, null);
+
+ assertEquals(searchResultEntry.getAttributes().size(), 4);
+ }
+
+ @Test
+ public void testSearchExternalAttributeWithSubtypesOmitValues()
+ throws Exception
+ {
+ LinkedHashSet<String> attributes = new LinkedHashSet<String>();
+ attributes.add("title");
+ SearchRequestProtocolOp searchRequest =
+ new SearchRequestProtocolOp(
+ new ASN1OctetString("o=test"),
+ SearchScope.WHOLE_SUBTREE,
+ DereferencePolicy.NEVER_DEREF_ALIASES,
+ Integer.MAX_VALUE,
+ Integer.MAX_VALUE,
+ true,
+ LDAPFilter.decode("(objectclass=inetorgperson)"),
+ attributes);
+
+ SearchResultEntryProtocolOp searchResultEntry =
+ searchExternalForSingleEntry(searchRequest, null);
+
+ assertEquals(searchResultEntry.getAttributes().size(), 4);
+ for (LDAPAttribute a : searchResultEntry.getAttributes())
+ {
+ assertEquals(a.getValues().size(), 0);
+ }
+ }
+
+ @Test
+ public void testSearchExternalAttributeWithOptions() throws Exception
+ {
+ LinkedHashSet<String> attributes = new LinkedHashSet<String>();
+ attributes.add("title;lang-ja;phonetic");
+ SearchRequestProtocolOp searchRequest =
+ new SearchRequestProtocolOp(
+ new ASN1OctetString("o=test"),
+ SearchScope.WHOLE_SUBTREE,
+ DereferencePolicy.NEVER_DEREF_ALIASES,
+ Integer.MAX_VALUE,
+ Integer.MAX_VALUE,
+ false,
+ LDAPFilter.decode("(objectclass=inetorgperson)"),
+ attributes);
+
+ SearchResultEntryProtocolOp searchResultEntry =
+ searchExternalForSingleEntry(searchRequest, null);
+
+ assertEquals(searchResultEntry.getAttributes().size(), 1);
+ }
+
+ @Test
+ public void testSearchExternalMatchedValues() throws Exception
+ {
+ // Add a matched values control.
+ LDAPFilter ldapFilter = LDAPFilter.decode("(title=*director*)");
+ MatchedValuesFilter matchedValuesFilter =
+ MatchedValuesFilter.createFromLDAPFilter(ldapFilter);
+ ArrayList<MatchedValuesFilter> filters =
+ new ArrayList<MatchedValuesFilter>();
+ filters.add(matchedValuesFilter);
+ MatchedValuesControl mvc = new MatchedValuesControl(true, filters);
+ ArrayList<LDAPControl> controls = new ArrayList<LDAPControl>();
+ controls.add(new LDAPControl(mvc));
+
+ SearchRequestProtocolOp searchRequest =
+ new SearchRequestProtocolOp(
+ new ASN1OctetString("o=test"),
+ SearchScope.WHOLE_SUBTREE,
+ DereferencePolicy.NEVER_DEREF_ALIASES,
+ Integer.MAX_VALUE,
+ Integer.MAX_VALUE,
+ false,
+ LDAPFilter.decode("(objectclass=inetorgperson)"),
+ null);
+
+ SearchResultEntryProtocolOp searchResultEntry =
+ searchExternalForSingleEntry(searchRequest, controls);
+
+ // Per RFC 3876, an attribute that has no values selected is returned
+ // with an empty set of values. We should therefore expect all the
+ // attributes but only one value.
+ int valueCount = 0;
+ for (LDAPAttribute a : searchResultEntry.getAttributes())
+ {
+ valueCount += a.getValues().size();
+ }
+ assertEquals(valueCount, 1);
+ }
+
}
--
Gitblit v1.10.0