issue# 3774: Sort control doesn't work for collation matching rules
1 files added
18 files modified
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.api; |
| | | |
| | | |
| | | |
| | | import java.util.Collection; |
| | | |
| | | import org.opends.server.types.ByteSequence; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ConditionResult; |
| | | import org.opends.server.types.DirectoryException; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class provides default implementation of MatchingRule. A |
| | | * matching rule implemented by a Directory Server module must extend |
| | | * this class. |
| | | */ |
| | | @org.opends.server.types.PublicAPI( |
| | | stability = org.opends.server.types.StabilityLevel.VOLATILE, |
| | | mayInstantiate = false, |
| | | mayExtend = true, |
| | | mayInvoke = false) |
| | | public abstract class AbstractMatchingRule implements MatchingRule |
| | | { |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public abstract String getName(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public abstract Collection<String> getAllNames(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public abstract String getOID(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ByteString normalizeAssertionValue(ByteSequence value) |
| | | throws DirectoryException |
| | | { |
| | | // Default implementation is to use attribute value normalization. |
| | | return normalizeValue(value); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public final String getNameOrOID() |
| | | { |
| | | String name = getName(); |
| | | if ((name == null) || (name.length() == 0)) |
| | | { |
| | | return getOID(); |
| | | } |
| | | else |
| | | { |
| | | return name; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public abstract String getDescription(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public abstract String getSyntaxOID(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isObsolete() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public abstract ByteString normalizeValue(ByteSequence value) |
| | | throws DirectoryException; |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ConditionResult valuesMatch( |
| | | ByteSequence attributeValue, ByteSequence assertionValue) |
| | | { |
| | | //Default implementation of most rule types. |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the hash code for this matching rule. It will be |
| | | * calculated as the sum of the characters in the OID. |
| | | * |
| | | * @return The hash code for this matching rule. |
| | | */ |
| | | @Override |
| | | public final int hashCode() |
| | | { |
| | | int hashCode = 0; |
| | | |
| | | String oidString = getOID(); |
| | | int oidLength = oidString.length(); |
| | | for (int i = 0; i < oidLength; i++) |
| | | { |
| | | hashCode += oidString.charAt(i); |
| | | } |
| | | |
| | | return hashCode; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided object is equal to this matching |
| | | * rule. The provided object will be considered equal to this |
| | | * matching rule only if it is a matching rule with the same OID. |
| | | * |
| | | * @param o |
| | | * The object for which to make the determination. |
| | | * @return {@code true} if the provided object is equal to this |
| | | * matching rule, or {@code false} if it is not. |
| | | */ |
| | | @Override |
| | | public final boolean equals(Object o) |
| | | { |
| | | if (o == null) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | if (this == o) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | if (!(o instanceof MatchingRule)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | return getOID().equals(((MatchingRule) o).getOID()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a string representation of this matching rule in the |
| | | * format defined in RFC 2252. |
| | | * |
| | | * @return A string representation of this matching rule in the |
| | | * format defined in RFC 2252. |
| | | */ |
| | | @Override |
| | | public final String toString() |
| | | { |
| | | StringBuilder buffer = new StringBuilder(); |
| | | toString(buffer); |
| | | return buffer.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public final void toString(StringBuilder buffer) |
| | | { |
| | | buffer.append("( "); |
| | | buffer.append(getOID()); |
| | | buffer.append(" NAME '"); |
| | | buffer.append(getName()); |
| | | |
| | | String description = getDescription(); |
| | | if ((description != null) && (description.length() > 0)) |
| | | { |
| | | buffer.append("' DESC '"); |
| | | buffer.append(description); |
| | | } |
| | | |
| | | if (isObsolete()) |
| | | { |
| | | buffer.append("' OBSOLETE SYNTAX "); |
| | | } |
| | | else |
| | | { |
| | | buffer.append("' SYNTAX "); |
| | | } |
| | | |
| | | buffer.append(getSyntaxOID()); |
| | | buffer.append(" )"); |
| | | } |
| | | } |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.api; |
| | | |
| | |
| | | mayExtend=true, |
| | | mayInvoke=false) |
| | | public abstract class ApproximateMatchingRule |
| | | extends MatchingRule |
| | | extends AbstractMatchingRule |
| | | implements MatchingRule |
| | | { |
| | | /** |
| | | * Indicates whether the two provided normalized values are |
| | |
| | | * if it does not match, or {@code UNDEFINED} if the result |
| | | * is undefined. |
| | | */ |
| | | @Override |
| | | public ConditionResult valuesMatch(ByteSequence attributeValue, |
| | | ByteSequence assertionValue) |
| | | { |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.api; |
| | | |
| | |
| | | mayInstantiate=false, |
| | | mayExtend=true, |
| | | mayInvoke=false) |
| | | public abstract class EqualityMatchingRule extends MatchingRule |
| | | public abstract class EqualityMatchingRule |
| | | extends AbstractMatchingRule |
| | | implements MatchingRule |
| | | { |
| | | /** |
| | | * Indicates whether the two provided normalized values are equal to |
| | |
| | | |
| | | |
| | | /** |
| | | * This class defines the set of methods and structures that must be |
| | | * This interface defines the set of methods that must be |
| | | * implemented by a Directory Server module that implements an |
| | | * Extensible matching rule. |
| | | */ |
| | |
| | | mayInstantiate = false, |
| | | mayExtend = true, |
| | | mayInvoke = false) |
| | | public abstract class ExtensibleMatchingRule extends MatchingRule |
| | | public interface ExtensibleMatchingRule extends MatchingRule |
| | | { |
| | | /** |
| | | * Returns a collection of extensible indexers associated with this |
| | |
| | | * @return The collection of extensible indexers associated with |
| | | * this matching rule. |
| | | */ |
| | | public abstract Collection<ExtensibleIndexer> getIndexers( |
| | | Collection<ExtensibleIndexer> getIndexers( |
| | | IndexConfig config); |
| | | |
| | | |
| | |
| | | * @throws DirectoryException |
| | | * If an error occurs while generating the index query. |
| | | */ |
| | | public abstract <T> T createIndexQuery(ByteSequence assertionValue, |
| | | <T> T createIndexQuery(ByteSequence assertionValue, |
| | | IndexQueryFactory<T> factory) throws DirectoryException; |
| | | } |
| | | } |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.api; |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * This class defines the set of methods and structures that must be |
| | | * implemented by a Directory Server module that implements a matching |
| | | * rule. |
| | | * This interface defines the set of methods that must be implemented |
| | | * by a Directory Server module that implements a matching rule. |
| | | */ |
| | | @org.opends.server.types.PublicAPI( |
| | | stability = org.opends.server.types.StabilityLevel.VOLATILE, |
| | | mayInstantiate = false, |
| | | mayExtend = true, |
| | | mayInvoke = false) |
| | | public abstract class MatchingRule |
| | | public interface MatchingRule |
| | | { |
| | | /** |
| | | * Retrieves the common name for this matching rule. |
| | |
| | | * @return The common name for this matching rule, or {@code null} |
| | | * if it does not have a name. |
| | | */ |
| | | public abstract String getName(); |
| | | String getName(); |
| | | |
| | | |
| | | |
| | |
| | | * |
| | | * @return All names for this matching rule. |
| | | */ |
| | | public abstract Collection<String> getAllNames(); |
| | | Collection<String> getAllNames(); |
| | | |
| | | |
| | | |
| | |
| | | * |
| | | * @return The OID for this matching rule. |
| | | */ |
| | | public abstract String getOID(); |
| | | String getOID(); |
| | | |
| | | |
| | | |
| | |
| | | * If the provided value is invalid according to the |
| | | * associated attribute syntax. |
| | | */ |
| | | public ByteString normalizeAssertionValue(ByteSequence value) |
| | | throws DirectoryException |
| | | { |
| | | // Default implementation is to use attribute value normalization. |
| | | return normalizeValue(value); |
| | | } |
| | | ByteString normalizeAssertionValue(ByteSequence value) |
| | | throws DirectoryException; |
| | | |
| | | |
| | | |
| | |
| | | * |
| | | * @return The name or OID for this matching rule. |
| | | */ |
| | | public final String getNameOrOID() |
| | | { |
| | | String name = getName(); |
| | | if ((name == null) || (name.length() == 0)) |
| | | { |
| | | return getOID(); |
| | | } |
| | | else |
| | | { |
| | | return name; |
| | | } |
| | | } |
| | | String getNameOrOID(); |
| | | |
| | | |
| | | |
| | |
| | | * @return The description for this matching rule, or {@code null} |
| | | * if there is none. |
| | | */ |
| | | public abstract String getDescription(); |
| | | String getDescription(); |
| | | |
| | | |
| | | |
| | |
| | | * @return The OID of the syntax with which this matching rule is |
| | | * associated. |
| | | */ |
| | | public abstract String getSyntaxOID(); |
| | | String getSyntaxOID(); |
| | | |
| | | |
| | | |
| | |
| | | * @return {@code true} if this matching rule is declared |
| | | * "OBSOLETE", or {@code false} if not. |
| | | */ |
| | | public boolean isObsolete() |
| | | { |
| | | return false; |
| | | } |
| | | boolean isObsolete(); |
| | | |
| | | |
| | | |
| | |
| | | * If the provided value is invalid according to the |
| | | * associated attribute syntax. |
| | | */ |
| | | public abstract ByteString normalizeValue(ByteSequence value) |
| | | ByteString normalizeValue(ByteSequence value) |
| | | throws DirectoryException; |
| | | |
| | | |
| | |
| | | * if it does not match, or {@code UNDEFINED} if the result |
| | | * is undefined. |
| | | */ |
| | | public abstract ConditionResult valuesMatch( |
| | | ConditionResult valuesMatch( |
| | | ByteSequence attributeValue, ByteSequence assertionValue); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the hash code for this matching rule. It will be |
| | | * calculated as the sum of the characters in the OID. |
| | | * |
| | | * @return The hash code for this matching rule. |
| | | */ |
| | | @Override |
| | | public final int hashCode() |
| | | { |
| | | int hashCode = 0; |
| | | |
| | | String oidString = getOID(); |
| | | int oidLength = oidString.length(); |
| | | for (int i = 0; i < oidLength; i++) |
| | | { |
| | | hashCode += oidString.charAt(i); |
| | | } |
| | | |
| | | return hashCode; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided object is equal to this matching |
| | | * rule. The provided object will be considered equal to this |
| | | * matching rule only if it is a matching rule with the same OID. |
| | | * |
| | | * @param o |
| | | * The object for which to make the determination. |
| | | * @return {@code true} if the provided object is equal to this |
| | | * matching rule, or {@code false} if it is not. |
| | | */ |
| | | @Override |
| | | public final boolean equals(Object o) |
| | | { |
| | | if (o == null) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | if (this == o) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | if (!(o instanceof MatchingRule)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | return getOID().equals(((MatchingRule) o).getOID()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a string representation of this matching rule in the |
| | | * format defined in RFC 2252. |
| | | * |
| | | * @return A string representation of this matching rule in the |
| | | * format defined in RFC 2252. |
| | | */ |
| | | @Override |
| | | public final String toString() |
| | | { |
| | | StringBuilder buffer = new StringBuilder(); |
| | | toString(buffer); |
| | | return buffer.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Appends a string representation of this matching rule in the |
| | | * format defined in RFC 2252 to the provided buffer. |
| | | * |
| | | * @param buffer |
| | | * The buffer to which the information should be appended. |
| | | */ |
| | | public final void toString(StringBuilder buffer) |
| | | { |
| | | buffer.append("( "); |
| | | buffer.append(getOID()); |
| | | buffer.append(" NAME '"); |
| | | buffer.append(getName()); |
| | | |
| | | String description = getDescription(); |
| | | if ((description != null) && (description.length() > 0)) |
| | | { |
| | | buffer.append("' DESC '"); |
| | | buffer.append(description); |
| | | } |
| | | |
| | | if (isObsolete()) |
| | | { |
| | | buffer.append("' OBSOLETE SYNTAX "); |
| | | } |
| | | else |
| | | { |
| | | buffer.append("' SYNTAX "); |
| | | } |
| | | |
| | | buffer.append(getSyntaxOID()); |
| | | buffer.append(" )"); |
| | | } |
| | | void toString(StringBuilder buffer); |
| | | } |
| | |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Comparator; |
| | | |
| | | import org.opends.server.types.ConditionResult; |
| | | import org.opends.server.types.ByteSequence; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines the set of methods and structures that must be |
| | | * implemented by a Directory Server module that implements a matching |
| | | * This interface defines the set of methods that must be implemented |
| | | * by a Directory Server module that implements a matching |
| | | * rule used for determining the correct order of values when sorting |
| | | * or processing range filters. |
| | | */ |
| | |
| | | mayInstantiate=false, |
| | | mayExtend=true, |
| | | mayInvoke=false) |
| | | public abstract class OrderingMatchingRule |
| | | extends MatchingRule |
| | | implements Comparator<byte[]>, Serializable |
| | | public interface OrderingMatchingRule |
| | | extends MatchingRule,Comparator<byte[]>,Serializable |
| | | { |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler |
| | | * because this class implements the {@code java.io.Serializable} |
| | | * interface. This value was generated using the {@code serialver} |
| | | * command-line utility included with the Java SDK. |
| | | */ |
| | | private static final long serialVersionUID = -5322529685787024597L; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Compares the first value to the second and returns a value that |
| | | * indicates their relative order. |
| | | * |
| | |
| | | */ |
| | | public abstract int compareValues(ByteSequence value1, |
| | | ByteSequence value2); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided attribute value should be |
| | | * considered a match for the given assertion value. This will only |
| | | * be used for the purpose of extensible matching. |
| | | * <BR><BR> |
| | | * Note that ordering matching rules by default do not support |
| | | * extensible matching, and therefore this method will always return |
| | | * {@code UNDEFINED}. If an ordering matching rule does support |
| | | * extensible matching operations, then it should override this |
| | | * method and provide an appropriate implementation. |
| | | * |
| | | * @param attributeValue The attribute value in a form that has |
| | | * been normalized according to this |
| | | * matching rule. |
| | | * @param assertionValue The assertion value in a form that has |
| | | * been normalized according to this |
| | | * matching rule. |
| | | * |
| | | * @return {@code true} if the attribute value should be considered |
| | | * a match for the provided assertion value, or |
| | | * {@code false} if not. |
| | | */ |
| | | public ConditionResult valuesMatch(ByteSequence attributeValue, |
| | | ByteSequence assertionValue) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | } |
| | | |
| | |
| | | mayInstantiate=false, |
| | | mayExtend=true, |
| | | mayInvoke=false) |
| | | public abstract class SubstringMatchingRule extends MatchingRule |
| | | public abstract class SubstringMatchingRule |
| | | extends AbstractMatchingRule |
| | | implements MatchingRule |
| | | { |
| | | /** |
| | | * Normalizes the provided value fragment into a form that can be |
| | |
| | | |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided attribute value should be |
| | | * considered a match for the given assertion value. This will only |
| | | * be used for the purpose of extensible matching. |
| | | * <BR><BR> |
| | | * Note that substring matching rules by default do not support |
| | | * extensible matching, and therefore this method will always return |
| | | * {@code UNDEFINED}. If a substring matching rule does support |
| | | * extensible matching operations, then it should override this |
| | | * method and provide an appropriate implementation. |
| | | * |
| | | * @param attributeValue The attribute value in a form that has |
| | | * been normalized according to this |
| | | * matching rule. |
| | | * @param assertionValue The assertion value in a form that has |
| | | * been normalized according to this |
| | | * matching rule. |
| | | * |
| | | * @return {@code true} if the attribute value should be considered |
| | | * a match for the provided assertion value, or |
| | | * {@code false} if not. |
| | | */ |
| | | @Override |
| | | public ConditionResult valuesMatch(ByteSequence attributeValue, |
| | | ByteSequence assertionValue) |
| | | { |
| | | return ConditionResult.UNDEFINED; |
| | | } |
| | | } |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.replication.plugin; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import org.opends.server.api.AbstractMatchingRule; |
| | | import org.opends.server.api.OrderingMatchingRule; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ByteSequence; |
| | |
| | | * Used to establish an order between historical information and index them. |
| | | */ |
| | | public class HistoricalCsnOrderingMatchingRule |
| | | extends OrderingMatchingRule |
| | | extends AbstractMatchingRule |
| | | implements OrderingMatchingRule |
| | | { |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because this |
| | |
| | | * @param value2 second value to compare |
| | | * @return 0 when equals, -1 or 1 to establish order |
| | | */ |
| | | @Override |
| | | public int compareValues(ByteSequence value1, ByteSequence value2) |
| | | { |
| | | String[] token1 = value1.toString().split(":", 3); |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.schema; |
| | | |
| | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | |
| | | import org.opends.server.api.AbstractMatchingRule; |
| | | import org.opends.server.api.OrderingMatchingRule; |
| | | import org.opends.server.types.ByteSequence; |
| | | import org.opends.server.types.ByteString; |
| | |
| | | * and referenced in RFC 4519. |
| | | */ |
| | | class CaseExactOrderingMatchingRule |
| | | extends OrderingMatchingRule |
| | | extends AbstractMatchingRule |
| | | implements OrderingMatchingRule |
| | | { |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because this |
| | |
| | | * ascending order, or zero if there is no difference between the |
| | | * values with regard to ordering. |
| | | */ |
| | | @Override |
| | | public int compareValues(ByteSequence value1, ByteSequence value2) |
| | | { |
| | | return StaticUtils.compare(value1, value2); |
| | | return value1.compareTo(value2); |
| | | } |
| | | |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.schema; |
| | | |
| | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | |
| | | import org.opends.server.api.AbstractMatchingRule; |
| | | import org.opends.server.api.OrderingMatchingRule; |
| | | import org.opends.server.types.ByteSequence; |
| | | import org.opends.server.types.ByteString; |
| | |
| | | * and referenced in RFC 2252. |
| | | */ |
| | | public class CaseIgnoreOrderingMatchingRule |
| | | extends OrderingMatchingRule |
| | | extends AbstractMatchingRule |
| | | implements OrderingMatchingRule |
| | | { |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because this |
| | |
| | | * ascending order, or zero if there is no difference between the |
| | | * values with regard to ordering. |
| | | */ |
| | | @Override |
| | | public int compareValues(ByteSequence value1, ByteSequence value2) |
| | | { |
| | | return StaticUtils.compare(value1, value2); |
| | | return value1.compareTo(value2); |
| | | } |
| | | |
| | | |
| | |
| | | import org.opends.server.admin.std.meta. |
| | | CollationMatchingRuleCfgDefn.MatchingRuleType; |
| | | import org.opends.server.admin.std.server.CollationMatchingRuleCfg; |
| | | import org.opends.server.api.AbstractMatchingRule; |
| | | import org.opends.server.api.ExtensibleIndexer; |
| | | import org.opends.server.api.ExtensibleMatchingRule; |
| | | import org.opends.server.api.IndexQueryFactory; |
| | | import org.opends.server.api.MatchingRule; |
| | | import org.opends.server.api.MatchingRuleFactory; |
| | | import org.opends.server.api.OrderingMatchingRule; |
| | | import org.opends.server.backends.jeb.AttributeIndex; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.core.DirectoryServer; |
| | |
| | | import org.opends.server.types.IndexConfig; |
| | | import org.opends.server.types.InitializationException; |
| | | import org.opends.server.types.ResultCode; |
| | | import org.opends.server.util.StaticUtils; |
| | | |
| | | |
| | | |
| | |
| | | /** |
| | | * Collation Extensible matching rule. |
| | | */ |
| | | private abstract class CollationMatchingRule extends |
| | | ExtensibleMatchingRule |
| | | private abstract class CollationMatchingRule |
| | | extends AbstractMatchingRule |
| | | implements ExtensibleMatchingRule |
| | | { |
| | | // Names for this class. |
| | | private final Collection<String> names; |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Collection<ExtensibleIndexer> getIndexers(IndexConfig config) |
| | | { |
| | | if (indexer == null) |
| | |
| | | /** |
| | | * Collation rule for Equality matching rule. |
| | | */ |
| | | private final class CollationEqualityMatchingRule extends |
| | | CollationMatchingRule |
| | | private final class CollationEqualityMatchingRule |
| | | extends CollationMatchingRule |
| | | implements OrderingMatchingRule |
| | | { |
| | | |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because |
| | | * this class implements the <CODE>java.io.Serializable</CODE> interface. |
| | | * This value was generated using the <CODE>serialver</CODE> command-line |
| | | * utility included with the Java SDK. |
| | | */ |
| | | private static final long serialVersionUID = 3990778178484159862L; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Constructs a new CollationEqualityMatchingRule. |
| | | * |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <T> T createIndexQuery(ByteSequence assertionValue, |
| | | IndexQueryFactory<T> factory) throws DirectoryException |
| | | { |
| | |
| | | return factory.createExactMatchQuery(indexer |
| | | .getExtensibleIndexID(), normalizeValue(assertionValue)); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int compare(byte[] arg0, byte[] arg1) |
| | | { |
| | | return StaticUtils.compare(arg0, arg1); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int compareValues(ByteSequence value1, ByteSequence value2) |
| | | { |
| | | return value1.compareTo(value2); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <T> T createIndexQuery(ByteSequence assertionValue, |
| | | IndexQueryFactory<T> factory) throws DirectoryException |
| | | { |
| | |
| | | /** |
| | | * An abstract Collation rule for Ordering matching rule. |
| | | */ |
| | | private abstract class CollationOrderingMatchingRule extends |
| | | CollationMatchingRule |
| | | private abstract class CollationOrderingMatchingRule |
| | | extends CollationMatchingRule |
| | | implements OrderingMatchingRule |
| | | { |
| | | |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because |
| | | * this class implements the <CODE>java.io.Serializable</CODE> interface. |
| | | * This value was generated using the <CODE>serialver</CODE> command-line |
| | | * utility included with the Java SDK. |
| | | */ |
| | | private static final long serialVersionUID = 7354051060508436941L; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Constructs a new CollationOrderingMatchingRule. |
| | | * |
| | |
| | | CollationKey key = collator.getCollationKey(value.toString()); |
| | | return ByteString.wrap(key.toByteArray()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int compare(byte[] arg0, byte[] arg1) |
| | | { |
| | | return StaticUtils.compare(arg0, arg1); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int compareValues(ByteSequence value1, ByteSequence value2) |
| | | { |
| | | return value1.compareTo(value2); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | private final class CollationLessThanMatchingRule extends |
| | | CollationOrderingMatchingRule |
| | | { |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because |
| | | * this class implements the <CODE>java.io.Serializable</CODE> interface. |
| | | * This value was generated using the <CODE>serialver</CODE> command-line |
| | | * utility included with the Java SDK. |
| | | */ |
| | | private static final long serialVersionUID = -7578406829946732713L; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Constructs a new CollationLessThanMatchingRule. |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <T> T createIndexQuery(ByteSequence assertionValue, |
| | | IndexQueryFactory<T> factory) throws DirectoryException |
| | | { |
| | |
| | | private final class CollationLessThanOrEqualToMatchingRule extends |
| | | CollationOrderingMatchingRule |
| | | { |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because |
| | | * this class implements the <CODE>java.io.Serializable</CODE> interface. |
| | | * This value was generated using the <CODE>serialver</CODE> command-line |
| | | * utility included with the Java SDK. |
| | | */ |
| | | private static final long serialVersionUID = 7222067708233629974L; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Constructs a new CollationLessThanOrEqualToMatchingRule. |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <T> T createIndexQuery(ByteSequence assertionValue, |
| | | IndexQueryFactory<T> factory) throws DirectoryException |
| | | { |
| | |
| | | private final class CollationGreaterThanMatchingRule extends |
| | | CollationOrderingMatchingRule |
| | | { |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because |
| | | * this class implements the <CODE>java.io.Serializable</CODE> interface. |
| | | * This value was generated using the <CODE>serialver</CODE> command-line |
| | | * utility included with the Java SDK. |
| | | */ |
| | | private static final long serialVersionUID = 1204368277332957024L; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Constructs a new CollationGreaterThanMatchingRule. |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <T> T createIndexQuery(ByteSequence assertionValue, |
| | | IndexQueryFactory<T> factory) throws DirectoryException |
| | | { |
| | |
| | | private final class CollationGreaterThanOrEqualToMatchingRule extends |
| | | CollationOrderingMatchingRule |
| | | { |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because |
| | | * this class implements the <CODE>java.io.Serializable</CODE> interface. |
| | | * This value was generated using the <CODE>serialver</CODE> command-line |
| | | * utility included with the Java SDK. |
| | | */ |
| | | private static final long serialVersionUID = -5212358378014047933L; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Constructs a new CollationGreaterThanOrEqualToMatchingRule. |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <T> T createIndexQuery(ByteSequence assertionValue, |
| | | IndexQueryFactory<T> factory) throws DirectoryException |
| | | { |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.schema; |
| | | |
| | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | |
| | | import org.opends.server.api.AbstractMatchingRule; |
| | | import org.opends.server.api.OrderingMatchingRule; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.loggers.debug.DebugTracer; |
| | |
| | | * X.520 and referenced in RFC 2252. |
| | | */ |
| | | class GeneralizedTimeOrderingMatchingRule |
| | | extends OrderingMatchingRule |
| | | extends AbstractMatchingRule |
| | | implements OrderingMatchingRule |
| | | { |
| | | /** |
| | | * The tracer object for the debug logger. |
| | |
| | | * ascending order, or zero if there is no difference between the |
| | | * values with regard to ordering. |
| | | */ |
| | | @Override |
| | | public int compareValues(ByteSequence value1, ByteSequence value2) |
| | | { |
| | | try |
| | |
| | | public int compare(byte[] b1, byte[] b2) |
| | | { |
| | | return compareValues(ByteString.wrap(b1), ByteString.wrap(b2)); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.schema; |
| | | |
| | |
| | | import java.util.Collections; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.api.AbstractMatchingRule; |
| | | import org.opends.server.api.OrderingMatchingRule; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.types.ByteSequence; |
| | |
| | | * and referenced in RFC 4519. |
| | | */ |
| | | class IntegerOrderingMatchingRule |
| | | extends OrderingMatchingRule |
| | | extends AbstractMatchingRule |
| | | implements OrderingMatchingRule |
| | | { |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because this |
| | |
| | | * ascending order, or zero if there is no difference between the |
| | | * values with regard to ordering. |
| | | */ |
| | | @Override |
| | | public int compareValues(ByteSequence value1, ByteSequence value2) |
| | | { |
| | | int b1Length = value1.length(); |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.schema; |
| | | |
| | |
| | | import java.util.Collections; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.api.AbstractMatchingRule; |
| | | import org.opends.server.api.OrderingMatchingRule; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.loggers.ErrorLogger; |
| | |
| | | * in X.520 and referenced in RFC 2252. |
| | | */ |
| | | class NumericStringOrderingMatchingRule |
| | | extends OrderingMatchingRule |
| | | extends AbstractMatchingRule |
| | | implements OrderingMatchingRule |
| | | { |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because this |
| | |
| | | * ascending order, or zero if there is no difference between the |
| | | * values with regard to ordering. |
| | | */ |
| | | @Override |
| | | public int compareValues(ByteSequence value1, ByteSequence value2) |
| | | { |
| | | return StaticUtils.compare(value1, value2); |
| | | return value1.compareTo(value2); |
| | | } |
| | | |
| | | |
| | |
| | | public int compare(byte[] b1, byte[] b2) |
| | | { |
| | | return StaticUtils.compare(b1, b2); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.schema; |
| | | |
| | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | |
| | | import org.opends.server.api.AbstractMatchingRule; |
| | | import org.opends.server.api.OrderingMatchingRule; |
| | | import org.opends.server.types.ByteSequence; |
| | | import org.opends.server.types.ByteString; |
| | |
| | | * octet string syntaxes. |
| | | */ |
| | | class OctetStringOrderingMatchingRule |
| | | extends OrderingMatchingRule |
| | | extends AbstractMatchingRule |
| | | implements OrderingMatchingRule |
| | | { |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because this |
| | |
| | | * ascending order, or zero if there is no difference between the |
| | | * values with regard to ordering. |
| | | */ |
| | | @Override |
| | | public int compareValues(ByteSequence value1, ByteSequence value2) |
| | | { |
| | | return StaticUtils.compare(value1, value2); |
| | | return value1.compareTo(value2); |
| | | } |
| | | |
| | | |
| | |
| | | public int compare(byte[] b1, byte[] b2) |
| | | { |
| | | return StaticUtils.compare(b1, b2); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.schema; |
| | | |
| | |
| | | import java.util.Collections; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.api.AbstractMatchingRule; |
| | | import org.opends.server.api.OrderingMatchingRule; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.loggers.ErrorLogger; |
| | |
| | | * This will be the default ordering matching rule for the UUID syntax. |
| | | */ |
| | | class UUIDOrderingMatchingRule |
| | | extends OrderingMatchingRule |
| | | extends AbstractMatchingRule |
| | | implements OrderingMatchingRule |
| | | { |
| | | /** |
| | | * The serial version identifier required to satisfy the compiler because this |
| | |
| | | * ascending order, or zero if there is no difference between the |
| | | * values with regard to ordering. |
| | | */ |
| | | @Override |
| | | public int compareValues(ByteSequence value1, ByteSequence value2) |
| | | { |
| | | return StaticUtils.compare(value1, value2); |
| | | return value1.compareTo(value2); |
| | | } |
| | | |
| | | |
| | |
| | | public int compare(byte[] b1, byte[] b2) |
| | | { |
| | | return StaticUtils.compare(b1, b2); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | public ExtensibleMatchingRule getExtensibleMatchingRule( |
| | | String lowerName) |
| | | { |
| | | return extensibleMatchingRules.get(lowerName); |
| | | //An ExtensibleMatchingRule can be of multiple types. |
| | | MatchingRule rule = matchingRules.get(lowerName); |
| | | if(rule instanceof ExtensibleMatchingRule) |
| | | { |
| | | return (ExtensibleMatchingRule)rule; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | |
| | | * if the first byte array is less than, equal to, or greater |
| | | * than the second. |
| | | */ |
| | | @Deprecated |
| | | public static int compare(ByteSequence a, ByteSequence a2) { |
| | | if (a == a2) { |
| | | return 0; |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | |
| | | package org.opends.server.schema; |
| | | |
| | | import java.util.ArrayList; |
| | | import static org.testng.Assert.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.controls.ServerSideSortRequestControl; |
| | | import org.opends.server.controls.VLVRequestControl; |
| | | import org.opends.server.protocols.internal.InternalClientConnection; |
| | | import org.opends.server.protocols.internal.InternalSearchOperation; |
| | | import org.opends.server.protocols.ldap.LDAPFilter; |
| | | import org.opends.server.tools.LDAPModify; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.Control; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DereferencePolicy; |
| | | import org.opends.server.types.Entry; |
| | | import org.opends.server.types.ResultCode; |
| | | import org.opends.server.types.SearchFilter; |
| | | import org.opends.server.types.SearchResultEntry; |
| | | import org.opends.server.types.SearchScope; |
| | | import org.testng.annotations.BeforeClass; |
| | |
| | | { |
| | | TestCaseUtils.startServer(); |
| | | TestCaseUtils.initializeTestBackend(true); |
| | | user1 = DN.decode("cn=user1,dc=example,dc=com"); |
| | | user2 = DN.decode("cn=user2,dc=example,dc=com"); |
| | | user3 = DN.decode("cn=user3,dc=example,dc=com"); |
| | | user4 = DN.decode("cn=user4,dc=example,dc=com"); |
| | | } |
| | | |
| | | |
| | |
| | | //An entry must be returned for sn=quebec. |
| | | assertNotNull(e); |
| | | } |
| | | |
| | | private DN user1; |
| | | private DN user2 ; |
| | | private DN user3; |
| | | private DN user4; |
| | | |
| | | |
| | | /** |
| | | * Test to verify the Sort control works well with the Collation |
| | | * Less-than-equal-to matching rule and French Locale. |
| | | */ |
| | | @Test() |
| | | public void testSortControlLTERule() throws Exception |
| | | { |
| | | ArrayList<DN> expectedDNOrder = new ArrayList<DN>(); |
| | | expectedDNOrder.add(user4); |
| | | expectedDNOrder.add(user3); |
| | | expectedDNOrder.add(user2); |
| | | expectedDNOrder.add(user1); |
| | | ArrayList<Control> requestControls = new ArrayList<Control>(); |
| | | requestControls.add(new ServerSideSortRequestControl("displayname:fr")); |
| | | ValidateSortControl(expectedDNOrder, |
| | | requestControls, |
| | | "displayname:fr-FR.6:=A*"); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Test to verify the Sort control works with Collation equality |
| | | * matching rule and Spanish locale. |
| | | */ |
| | | @Test() |
| | | public void testSortControlEQRule() throws Exception |
| | | { |
| | | ArrayList<DN> expectedDNOrder = new ArrayList<DN>(); |
| | | expectedDNOrder.add(user4); |
| | | expectedDNOrder.add(user3); |
| | | expectedDNOrder.add(user2); |
| | | expectedDNOrder.add(user1); |
| | | ArrayList<Control> requestControls = new ArrayList<Control>(); |
| | | requestControls.add(new ServerSideSortRequestControl("displayname:es")); |
| | | ValidateSortControl(expectedDNOrder, |
| | | requestControls, |
| | | "displayname:es.6:=A*"); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Test to verify the Sort control works with Collation greater |
| | | * than matching rule and English locale in a descending order. |
| | | */ |
| | | @Test() |
| | | public void testSortControlGTRule() throws Exception |
| | | { |
| | | ArrayList<DN> expectedDNOrder = new ArrayList<DN>(); |
| | | expectedDNOrder.add(user1); |
| | | expectedDNOrder.add(user2); |
| | | expectedDNOrder.add(user3); |
| | | expectedDNOrder.add(user4); |
| | | ArrayList<Control> requestControls = new ArrayList<Control>(); |
| | | requestControls.add(new ServerSideSortRequestControl("-displayname:en")); |
| | | ValidateSortControl(expectedDNOrder, |
| | | requestControls, |
| | | "displayname:en-US.6:=A*"); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the Sort control with the VLV control using a collation equality |
| | | * matching rule. |
| | | */ |
| | | @Test() |
| | | public void testVLVSortControl() throws Exception |
| | | { |
| | | ArrayList<DN> expectedDNOrder = new ArrayList<DN>(); |
| | | expectedDNOrder.add(user4); |
| | | expectedDNOrder.add(user3); |
| | | expectedDNOrder.add(user2); |
| | | expectedDNOrder.add(user1); |
| | | ArrayList<Control> requestControls = new ArrayList<Control>(); |
| | | requestControls.add(new ServerSideSortRequestControl("displayname:fr")); |
| | | requestControls.add(new VLVRequestControl(0, 4, 1, 0)); |
| | | ValidateSortControl(expectedDNOrder, |
| | | requestControls, |
| | | "objectclass=inetOrgPerson"); |
| | | } |
| | | |
| | | |
| | | |
| | | private void ValidateSortControl(ArrayList<DN> expectedDNOrder, |
| | | ArrayList<Control> requestControls, |
| | | String searchFilter) throws Exception |
| | | { |
| | | try |
| | | { |
| | | populateEntriesForControl(); |
| | | InternalClientConnection conn = |
| | | InternalClientConnection.getRootConnection(); |
| | | |
| | | InternalSearchOperation internalSearch = |
| | | new InternalSearchOperation(conn, InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), requestControls, |
| | | DN.decode("dc=example,dc=com"), SearchScope.WHOLE_SUBTREE, |
| | | DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false, |
| | | SearchFilter.createFilterFromString(searchFilter), |
| | | null, null); |
| | | |
| | | internalSearch.run(); |
| | | assertEquals(internalSearch.getResultCode(), ResultCode.SUCCESS); |
| | | ArrayList<DN> returnedDNOrder = new ArrayList<DN>(); |
| | | for (Entry e : internalSearch.getSearchEntries()) |
| | | { |
| | | returnedDNOrder.add(e.getDN()); |
| | | } |
| | | assertEquals(returnedDNOrder, expectedDNOrder); |
| | | } |
| | | finally |
| | | { |
| | | TestCaseUtils.clearJEBackend(false, "userRoot", "dc=example,dc=com"); |
| | | } |
| | | } |
| | | |
| | | |
| | | private void populateEntriesForControl() throws Exception |
| | | { |
| | | TestCaseUtils.clearJEBackend(true, "userRoot", "dc=example,dc=com"); |
| | | TestCaseUtils.addEntries( |
| | | "dn: cn=user1,dc=example,dc=com", |
| | | "objectclass: inetorgperson", |
| | | "cn: user1", |
| | | "sn: user1", |
| | | "uid: user1", |
| | | "displayname:: QXVy4oiawqlsaWVuNA==", |
| | | "", |
| | | "dn: cn=user2,dc=example,dc=com", |
| | | "objectclass: inetorgperson", |
| | | "cn: user2", |
| | | "sn: user2", |
| | | "uid: user2", |
| | | "displayname:: QXVy4oiawqlsaWVuMw==", |
| | | "", |
| | | "dn: cn=user3,dc=example,dc=com", |
| | | "objectclass: inetorgperson", |
| | | "cn: user3", |
| | | "sn: user3", |
| | | "uid: user3", |
| | | "displayname:: QXVy4oiawqlsaWVuMg==", |
| | | "", |
| | | "dn: cn=user4,dc=example,dc=com", |
| | | "objectclass: inetorgperson", |
| | | "cn: user4", |
| | | "sn: user4", |
| | | "uid: user4", |
| | | "displayname:: QXVy4oiawqlsaWVuMQ==" |
| | | ); |
| | | } |
| | | } |