Search in sources :

Example 6 with MatchingRule

use of com.unboundid.ldap.matchingrules.MatchingRule in project ldapsdk by pingidentity.

the class EntryValidator method checkAttribute.

/**
 * Checks the provided attribute to determine whether it appears to be valid.
 *
 * @param  attr            The attribute to examine.
 * @param  requiredAttrs   The set of attribute types which are required to be
 *                         included in the entry.
 * @param  optionalAttrs   The set of attribute types which may optionally be
 *                         included in the entry.
 * @param  invalidReasons  A list to which messages may be added which provide
 *                         information about why the entry is invalid.  It may
 *                         be {@code null} if this information is not needed.
 *
 * @return  {@code true} if the attribute passed all of the checks and appears
 *          to be valid, or {@code false} if it failed any of the checks.
 */
private boolean checkAttribute(@NotNull final Attribute attr, @NotNull final Set<AttributeTypeDefinition> requiredAttrs, @NotNull final Set<AttributeTypeDefinition> optionalAttrs, @Nullable final List<String> invalidReasons) {
    boolean entryValid = true;
    final AttributeTypeDefinition d = schema.getAttributeType(attr.getBaseName());
    if (d == null) {
        if (checkUndefinedAttributes) {
            entryValid = false;
            updateCount(attr.getBaseName(), undefinedAttributes);
            if (invalidReasons != null) {
                invalidReasons.add(ERR_ENTRY_UNDEFINED_ATTR.get(attr.getBaseName()));
            }
        }
        return entryValid;
    }
    if (checkProhibitedAttributes && (!d.isOperational())) {
        if (!(requiredAttrs.contains(d) || optionalAttrs.contains(d))) {
            entryValid = false;
            updateCount(d.getNameOrOID(), prohibitedAttributes);
            if (invalidReasons != null) {
                invalidReasons.add(ERR_ENTRY_ATTR_NOT_ALLOWED.get(d.getNameOrOID()));
            }
        }
    }
    final ASN1OctetString[] rawValues = attr.getRawValues();
    if (checkSingleValuedAttributes && d.isSingleValued() && (rawValues.length > 1)) {
        entryValid = false;
        updateCount(d.getNameOrOID(), singleValueViolations);
        if (invalidReasons != null) {
            invalidReasons.add(ERR_ENTRY_ATTR_HAS_MULTIPLE_VALUES.get(d.getNameOrOID()));
        }
    }
    if (checkAttributeSyntax) {
        if (!ignoreSyntaxViolationTypes.contains(d)) {
            final MatchingRule r = MatchingRule.selectEqualityMatchingRule(d.getNameOrOID(), schema);
            final Map<String, String[]> extensions = d.getExtensions();
            for (final ASN1OctetString v : rawValues) {
                try {
                    r.normalize(v);
                } catch (final LDAPException le) {
                    Debug.debugException(le);
                    entryValid = false;
                    updateCount(d.getNameOrOID(), attributesViolatingSyntax);
                    if (invalidReasons != null) {
                        invalidReasons.add(ERR_ENTRY_ATTR_INVALID_SYNTAX.get(v.stringValue(), d.getNameOrOID(), StaticUtils.getExceptionMessage(le)));
                    }
                }
                // If the attribute type definition includes an X-ALLOWED-VALUE
                // extension, then make sure the value is in that set.
                final String[] allowedValues = extensions.get("X-ALLOWED-VALUE");
                if (allowedValues != null) {
                    boolean isAllowed = false;
                    for (final String allowedValue : allowedValues) {
                        try {
                            if (r.valuesMatch(v, new ASN1OctetString(allowedValue))) {
                                isAllowed = true;
                                break;
                            }
                        } catch (final Exception e) {
                            Debug.debugException(e);
                        }
                    }
                    if (!isAllowed) {
                        entryValid = false;
                        updateCount(d.getNameOrOID(), attributesViolatingSyntax);
                        if (invalidReasons != null) {
                            invalidReasons.add(ERR_ENTRY_ATTR_VALUE_NOT_ALLOWED.get(v.stringValue(), d.getNameOrOID()));
                        }
                    }
                }
                // If the attribute type definition includes an X-VALUE-REGEX
                // extension, then make sure the value matches one of those regexes.
                final String[] valueRegexes = extensions.get("X-VALUE-REGEX");
                if (valueRegexes != null) {
                    boolean matchesRegex = false;
                    for (final String regex : valueRegexes) {
                        try {
                            final Pattern pattern = Pattern.compile(regex);
                            if (pattern.matcher(v.stringValue()).matches()) {
                                matchesRegex = true;
                                break;
                            }
                        } catch (final Exception e) {
                            Debug.debugException(e);
                        }
                    }
                    if (!matchesRegex) {
                        entryValid = false;
                        updateCount(d.getNameOrOID(), attributesViolatingSyntax);
                        if (invalidReasons != null) {
                            invalidReasons.add(ERR_ENTRY_ATTR_VALUE_NOT_ALLOWED_BY_REGEX.get(v.stringValue(), d.getNameOrOID()));
                        }
                    }
                }
                // If the attribute type definition includes an X-MIN-VALUE-LENGTH
                // extension, then make sure the value is long enough.
                final String[] minValueLengths = extensions.get("X-MIN-VALUE-LENGTH");
                if (minValueLengths != null) {
                    int minLength = 0;
                    for (final String s : minValueLengths) {
                        try {
                            minLength = Math.max(minLength, Integer.parseInt(s));
                        } catch (final Exception e) {
                            Debug.debugException(e);
                        }
                    }
                    if (v.stringValue().length() < minLength) {
                        entryValid = false;
                        updateCount(d.getNameOrOID(), attributesViolatingSyntax);
                        if (invalidReasons != null) {
                            invalidReasons.add(ERR_ENTRY_ATTR_VALUE_SHORTER_THAN_MIN_LENGTH.get(v.stringValue(), d.getNameOrOID(), minLength));
                        }
                    }
                }
                // If the attribute type definition includes an X-MAX-VALUE-LENGTH
                // extension, then make sure the value is short enough.
                final String[] maxValueLengths = extensions.get("X-MAX-VALUE-LENGTH");
                if (maxValueLengths != null) {
                    int maxLength = Integer.MAX_VALUE;
                    for (final String s : maxValueLengths) {
                        try {
                            maxLength = Math.min(maxLength, Integer.parseInt(s));
                        } catch (final Exception e) {
                            Debug.debugException(e);
                        }
                    }
                    if (v.stringValue().length() > maxLength) {
                        entryValid = false;
                        updateCount(d.getNameOrOID(), attributesViolatingSyntax);
                        if (invalidReasons != null) {
                            invalidReasons.add(ERR_ENTRY_ATTR_VALUE_LONGER_THAN_MAX_LENGTH.get(v.stringValue(), d.getNameOrOID(), maxLength));
                        }
                    }
                }
                // If the attribute type definition includes an X-MIN-INT-VALUE
                // extension, then make sure the value is large enough.
                final String[] minIntValues = extensions.get("X-MIN-INT-VALUE");
                if (minIntValues != null) {
                    try {
                        final long longValue = Long.parseLong(v.stringValue());
                        long minAllowedValue = 0L;
                        for (final String s : minIntValues) {
                            try {
                                minAllowedValue = Math.max(minAllowedValue, Long.parseLong(s));
                            } catch (final Exception e) {
                                Debug.debugException(e);
                            }
                        }
                        if (longValue < minAllowedValue) {
                            entryValid = false;
                            updateCount(d.getNameOrOID(), attributesViolatingSyntax);
                            if (invalidReasons != null) {
                                invalidReasons.add(ERR_ENTRY_ATTR_VALUE_INT_TOO_SMALL.get(longValue, d.getNameOrOID(), minAllowedValue));
                            }
                        }
                    } catch (final Exception e) {
                        Debug.debugException(e);
                        entryValid = false;
                        updateCount(d.getNameOrOID(), attributesViolatingSyntax);
                        if (invalidReasons != null) {
                            invalidReasons.add(ERR_ENTRY_ATTR_VALUE_NOT_INT.get(v.stringValue(), d.getNameOrOID(), "X-MIN-INT-VALUE"));
                        }
                    }
                }
                // If the attribute type definition includes an X-MAX-INT-VALUE
                // extension, then make sure the value is large enough.
                final String[] maxIntValues = extensions.get("X-MAX-INT-VALUE");
                if (maxIntValues != null) {
                    try {
                        final long longValue = Long.parseLong(v.stringValue());
                        long maxAllowedValue = Long.MAX_VALUE;
                        for (final String s : maxIntValues) {
                            try {
                                maxAllowedValue = Math.min(maxAllowedValue, Long.parseLong(s));
                            } catch (final Exception e) {
                                Debug.debugException(e);
                            }
                        }
                        if (longValue > maxAllowedValue) {
                            entryValid = false;
                            updateCount(d.getNameOrOID(), attributesViolatingSyntax);
                            if (invalidReasons != null) {
                                invalidReasons.add(ERR_ENTRY_ATTR_VALUE_INT_TOO_LARGE.get(longValue, d.getNameOrOID(), maxAllowedValue));
                            }
                        }
                    } catch (final Exception e) {
                        Debug.debugException(e);
                        entryValid = false;
                        updateCount(d.getNameOrOID(), attributesViolatingSyntax);
                        if (invalidReasons != null) {
                            invalidReasons.add(ERR_ENTRY_ATTR_VALUE_NOT_INT.get(v.stringValue(), d.getNameOrOID(), "X-MAX-INT-VALUE"));
                        }
                    }
                }
            }
            // If the attribute type definition includes an X-MIN-VALUE-COUNT
            // extension, then make sure the value has enough values.
            final String[] minValueCounts = extensions.get("X-MIN-VALUE-COUNT");
            if (minValueCounts != null) {
                int minValueCount = 0;
                for (final String s : minValueCounts) {
                    try {
                        minValueCount = Math.max(minValueCount, Integer.parseInt(s));
                    } catch (final Exception e) {
                        Debug.debugException(e);
                    }
                }
                if (rawValues.length < minValueCount) {
                    entryValid = false;
                    updateCount(d.getNameOrOID(), attributesViolatingSyntax);
                    if (invalidReasons != null) {
                        invalidReasons.add(ERR_ENTRY_TOO_FEW_VALUES.get(rawValues.length, d.getNameOrOID(), minValueCount));
                    }
                }
            }
            // If the attribute type definition includes an X-MAX-VALUE-COUNT
            // extension, then make sure the value has enough values.
            final String[] maxValueCounts = extensions.get("X-MAX-VALUE-COUNT");
            if (maxValueCounts != null) {
                int maxValueCount = Integer.MAX_VALUE;
                for (final String s : maxValueCounts) {
                    try {
                        maxValueCount = Math.min(maxValueCount, Integer.parseInt(s));
                    } catch (final Exception e) {
                        Debug.debugException(e);
                    }
                }
                if (rawValues.length > maxValueCount) {
                    entryValid = false;
                    updateCount(d.getNameOrOID(), attributesViolatingSyntax);
                    if (invalidReasons != null) {
                        invalidReasons.add(ERR_ENTRY_TOO_MANY_VALUES.get(rawValues.length, d.getNameOrOID(), maxValueCount));
                    }
                }
            }
        }
    }
    return entryValid;
}
Also used : ASN1OctetString(com.unboundid.asn1.ASN1OctetString) Pattern(java.util.regex.Pattern) ASN1OctetString(com.unboundid.asn1.ASN1OctetString) LDAPException(com.unboundid.ldap.sdk.LDAPException) LDAPException(com.unboundid.ldap.sdk.LDAPException) MatchingRule(com.unboundid.ldap.matchingrules.MatchingRule)

Example 7 with MatchingRule

use of com.unboundid.ldap.matchingrules.MatchingRule in project ldapsdk by pingidentity.

the class EntryValidator method checkRDN.

/**
 * Ensures that the provided RDN is acceptable.  It will ensure that all
 * attributes are defined in the schema and allowed for the entry, and that
 * the entry optionally conforms to the associated name form.
 *
 * @param  rdn             The RDN to examine.
 * @param  entry           The entry to examine.
 * @param  requiredAttrs   The set of attribute types which are required to be
 *                         included in the entry.
 * @param  optionalAttrs   The set of attribute types which may optionally be
 *                         included in the entry.
 * @param  nameForm        The name for to use to make the determination, if
 *                         defined.
 * @param  invalidReasons  A list to which messages may be added which provide
 *                         information about why the entry is invalid.  It may
 *                         be {@code null} if this information is not needed.
 *
 * @return  {@code true} if the entry passes all checks performed by this
 *          method, or {@code false} if not.
 */
private boolean checkRDN(@NotNull final RDN rdn, @NotNull final Entry entry, @NotNull final Set<AttributeTypeDefinition> requiredAttrs, @NotNull final Set<AttributeTypeDefinition> optionalAttrs, @Nullable final NameFormDefinition nameForm, @Nullable final List<String> invalidReasons) {
    final HashSet<AttributeTypeDefinition> nfReqAttrs = new HashSet<>(StaticUtils.computeMapCapacity(5));
    final HashSet<AttributeTypeDefinition> nfAllowedAttrs = new HashSet<>(StaticUtils.computeMapCapacity(5));
    if (nameForm != null) {
        for (final String s : nameForm.getRequiredAttributes()) {
            final AttributeTypeDefinition d = schema.getAttributeType(s);
            if (d != null) {
                nfReqAttrs.add(d);
            }
        }
        nfAllowedAttrs.addAll(nfReqAttrs);
        for (final String s : nameForm.getOptionalAttributes()) {
            final AttributeTypeDefinition d = schema.getAttributeType(s);
            if (d != null) {
                nfAllowedAttrs.add(d);
            }
        }
    }
    boolean entryValid = true;
    final String[] attributeNames = rdn.getAttributeNames();
    final byte[][] attributeValues = rdn.getByteArrayAttributeValues();
    for (int i = 0; i < attributeNames.length; i++) {
        final String name = attributeNames[i];
        if (checkEntryMissingRDNValues) {
            final byte[] value = attributeValues[i];
            final MatchingRule matchingRule = MatchingRule.selectEqualityMatchingRule(name, schema);
            if (!entry.hasAttributeValue(name, value, matchingRule)) {
                entryValid = false;
                entriesMissingRDNValues.incrementAndGet();
                if (invalidReasons != null) {
                    invalidReasons.add(ERR_ENTRY_MISSING_RDN_VALUE.get(rdn.getAttributeValues()[i], name));
                }
            }
        }
        final AttributeTypeDefinition d = schema.getAttributeType(name);
        if (d == null) {
            if (checkUndefinedAttributes) {
                entryValid = false;
                updateCount(name, undefinedAttributes);
                if (invalidReasons != null) {
                    invalidReasons.add(ERR_ENTRY_RDN_ATTR_NOT_DEFINED.get(name));
                }
            }
        } else {
            if (checkProhibitedAttributes && (!(requiredAttrs.contains(d) || optionalAttrs.contains(d) || d.isOperational()))) {
                entryValid = false;
                updateCount(d.getNameOrOID(), prohibitedAttributes);
                if (invalidReasons != null) {
                    invalidReasons.add(ERR_ENTRY_RDN_ATTR_NOT_ALLOWED_IN_ENTRY.get(d.getNameOrOID()));
                }
            }
            if (checkNameForms && (nameForm != null)) {
                if (!nfReqAttrs.remove(d)) {
                    if (!nfAllowedAttrs.contains(d)) {
                        if (entryValid) {
                            entryValid = false;
                            nameFormViolations.incrementAndGet();
                        }
                        if (invalidReasons != null) {
                            invalidReasons.add(ERR_ENTRY_RDN_ATTR_NOT_ALLOWED_BY_NF.get(name));
                        }
                    }
                }
            }
        }
    }
    if (checkNameForms && (!nfReqAttrs.isEmpty())) {
        if (entryValid) {
            entryValid = false;
            nameFormViolations.incrementAndGet();
        }
        if (invalidReasons != null) {
            for (final AttributeTypeDefinition d : nfReqAttrs) {
                invalidReasons.add(ERR_ENTRY_RDN_MISSING_REQUIRED_ATTR.get(d.getNameOrOID()));
            }
        }
    }
    return entryValid;
}
Also used : ASN1OctetString(com.unboundid.asn1.ASN1OctetString) MatchingRule(com.unboundid.ldap.matchingrules.MatchingRule) HashSet(java.util.HashSet)

Example 8 with MatchingRule

use of com.unboundid.ldap.matchingrules.MatchingRule in project ldapsdk by pingidentity.

the class Attribute method readFrom.

/**
 * Reads and decodes an attribute from the provided ASN.1 stream reader.
 *
 * @param  reader  The ASN.1 stream reader from which to read the attribute.
 * @param  schema  The schema to use to select the appropriate matching rule
 *                 for this attribute.  It may be {@code null} if the default
 *                 matching rule should be selected.
 *
 * @return  The decoded attribute.
 *
 * @throws  LDAPException  If a problem occurs while trying to read or decode
 *                         the attribute.
 */
@NotNull()
public static Attribute readFrom(@NotNull final ASN1StreamReader reader, @Nullable final Schema schema) throws LDAPException {
    try {
        Validator.ensureNotNull(reader.beginSequence());
        final String attrName = reader.readString();
        Validator.ensureNotNull(attrName);
        final MatchingRule matchingRule = MatchingRule.selectEqualityMatchingRule(attrName, schema);
        final ArrayList<ASN1OctetString> valueList = new ArrayList<>(10);
        final ASN1StreamReaderSet valueSet = reader.beginSet();
        while (valueSet.hasMoreElements()) {
            valueList.add(new ASN1OctetString(reader.readBytes()));
        }
        final ASN1OctetString[] values = new ASN1OctetString[valueList.size()];
        valueList.toArray(values);
        return new Attribute(attrName, matchingRule, values);
    } catch (final Exception e) {
        Debug.debugException(e);
        throw new LDAPException(ResultCode.DECODING_ERROR, ERR_ATTR_CANNOT_DECODE.get(StaticUtils.getExceptionMessage(e)), e);
    }
}
Also used : ASN1OctetString(com.unboundid.asn1.ASN1OctetString) ArrayList(java.util.ArrayList) ASN1StreamReaderSet(com.unboundid.asn1.ASN1StreamReaderSet) ASN1OctetString(com.unboundid.asn1.ASN1OctetString) MatchingRule(com.unboundid.ldap.matchingrules.MatchingRule) CaseIgnoreStringMatchingRule(com.unboundid.ldap.matchingrules.CaseIgnoreStringMatchingRule) ASN1Exception(com.unboundid.asn1.ASN1Exception) NotNull(com.unboundid.util.NotNull)

Example 9 with MatchingRule

use of com.unboundid.ldap.matchingrules.MatchingRule in project ldapsdk by pingidentity.

the class Filter method matchesEntry.

/**
 * Indicates whether this filter matches the provided entry.  Note that this
 * is a best-guess effort and may not be completely accurate in all cases.
 * If provided, the given schema will be used in an attempt to determine the
 * appropriate matching rule for making the determinations, but some corner
 * cases may not be handled accurately.  Neither approximate matching nor
 * extensible matching are currently supported.
 *
 * @param  entry   The entry for which to make the determination.  It must not
 *                 be {@code null}.
 * @param  schema  The schema to use when making the determination.  If this
 *                 is {@code null}, then all matching will be performed using
 *                 a case-ignore matching rule.
 *
 * @return  {@code true} if this filter appears to match the provided entry,
 *          or {@code false} if not.
 *
 * @throws  LDAPException  If a problem occurs while trying to make the
 *                         determination.
 */
public boolean matchesEntry(@NotNull final Entry entry, @Nullable final Schema schema) throws LDAPException {
    Validator.ensureNotNull(entry);
    switch(filterType) {
        case FILTER_TYPE_AND:
            for (final Filter f : filterComps) {
                try {
                    if (!f.matchesEntry(entry, schema)) {
                        return false;
                    }
                } catch (final Exception e) {
                    Debug.debugException(e);
                    return false;
                }
            }
            return true;
        case FILTER_TYPE_OR:
            for (final Filter f : filterComps) {
                try {
                    if (f.matchesEntry(entry, schema)) {
                        return true;
                    }
                } catch (final Exception e) {
                    Debug.debugException(e);
                }
            }
            return false;
        case FILTER_TYPE_NOT:
            return (!notComp.matchesEntry(entry, schema));
        case FILTER_TYPE_EQUALITY:
            Attribute a = entry.getAttribute(attrName, schema);
            if (a == null) {
                return false;
            }
            MatchingRule matchingRule = MatchingRule.selectEqualityMatchingRule(attrName, schema);
            return matchingRule.matchesAnyValue(assertionValue, a.getRawValues());
        case FILTER_TYPE_SUBSTRING:
            a = entry.getAttribute(attrName, schema);
            if (a == null) {
                return false;
            }
            matchingRule = MatchingRule.selectSubstringMatchingRule(attrName, schema);
            for (final ASN1OctetString v : a.getRawValues()) {
                if (matchingRule.matchesSubstring(v, subInitial, subAny, subFinal)) {
                    return true;
                }
            }
            return false;
        case FILTER_TYPE_GREATER_OR_EQUAL:
            a = entry.getAttribute(attrName, schema);
            if (a == null) {
                return false;
            }
            matchingRule = MatchingRule.selectOrderingMatchingRule(attrName, schema);
            for (final ASN1OctetString v : a.getRawValues()) {
                if (matchingRule.compareValues(v, assertionValue) >= 0) {
                    return true;
                }
            }
            return false;
        case FILTER_TYPE_LESS_OR_EQUAL:
            a = entry.getAttribute(attrName, schema);
            if (a == null) {
                return false;
            }
            matchingRule = MatchingRule.selectOrderingMatchingRule(attrName, schema);
            for (final ASN1OctetString v : a.getRawValues()) {
                if (matchingRule.compareValues(v, assertionValue) <= 0) {
                    return true;
                }
            }
            return false;
        case FILTER_TYPE_PRESENCE:
            return (entry.hasAttribute(attrName));
        case FILTER_TYPE_APPROXIMATE_MATCH:
            throw new LDAPException(ResultCode.NOT_SUPPORTED, ERR_FILTER_APPROXIMATE_MATCHING_NOT_SUPPORTED.get());
        case FILTER_TYPE_EXTENSIBLE_MATCH:
            return extensibleMatchFilterMatchesEntry(entry, schema);
        default:
            throw new LDAPException(ResultCode.PARAM_ERROR, ERR_FILTER_INVALID_TYPE.get());
    }
}
Also used : ASN1OctetString(com.unboundid.asn1.ASN1OctetString) JSONObjectFilter(com.unboundid.ldap.sdk.unboundidds.jsonfilter.JSONObjectFilter) MatchingRule(com.unboundid.ldap.matchingrules.MatchingRule) CaseIgnoreStringMatchingRule(com.unboundid.ldap.matchingrules.CaseIgnoreStringMatchingRule) ASN1Exception(com.unboundid.asn1.ASN1Exception)

Example 10 with MatchingRule

use of com.unboundid.ldap.matchingrules.MatchingRule in project ldapsdk by pingidentity.

the class EntrySorter method compare.

/**
 * Compares the provided entries to determine the order in which they should
 * be placed in a sorted list.
 *
 * @param  e1  The first entry to be compared.
 * @param  e2  The second entry to be compared.
 *
 * @return  A negative value if the first entry should be ordered before the
 *          second, a positive value if the first entry should be ordered
 *          after the second, or zero if the entries should have an equivalent
 *          order.
 */
@Override()
public int compare(@NotNull final Entry e1, @NotNull final Entry e2) {
    DN parsedDN1 = null;
    DN parsedDN2 = null;
    if (sortByHierarchy) {
        try {
            parsedDN1 = e1.getParsedDN();
            parsedDN2 = e2.getParsedDN();
            if (parsedDN1.isAncestorOf(parsedDN2, false)) {
                return -1;
            } else if (parsedDN2.isAncestorOf(parsedDN1, false)) {
                return 1;
            }
        } catch (final LDAPException le) {
            Debug.debugException(le);
        }
    }
    for (final SortKey k : sortKeys) {
        final String attrName = k.getAttributeName();
        final Attribute a1 = e1.getAttribute(attrName);
        final Attribute a2 = e2.getAttribute(attrName);
        if ((a1 == null) || (!a1.hasValue())) {
            if ((a2 == null) || (!a2.hasValue())) {
                // attribute.
                continue;
            } else {
                // The first entry should be ordered after the second.
                return 1;
            }
        } else {
            if ((a2 == null) || (!a2.hasValue())) {
                // first entry should be ordered before the second.
                return -1;
            }
        }
        final MatchingRule matchingRule = MatchingRule.selectOrderingMatchingRule(attrName, k.getMatchingRuleID(), schema);
        if (k.reverseOrder()) {
            // Find the largest value for each attribute, and pick the larger of the
            // two.
            ASN1OctetString v1 = null;
            for (final ASN1OctetString s : a1.getRawValues()) {
                if (v1 == null) {
                    v1 = s;
                } else {
                    try {
                        if (matchingRule.compareValues(s, v1) > 0) {
                            v1 = s;
                        }
                    } catch (final LDAPException le) {
                        Debug.debugException(le);
                    }
                }
            }
            ASN1OctetString v2 = null;
            for (final ASN1OctetString s : a2.getRawValues()) {
                if (v2 == null) {
                    v2 = s;
                } else {
                    try {
                        if (matchingRule.compareValues(s, v2) > 0) {
                            v2 = s;
                        }
                    } catch (final LDAPException le) {
                        Debug.debugException(le);
                    }
                }
            }
            try {
                final int value = matchingRule.compareValues(v2, v1);
                if (value != 0) {
                    return value;
                }
            } catch (final LDAPException le) {
                Debug.debugException(le);
            }
        } else {
            // Find the smallest value for each attribute, and pick the larger of
            // the two.
            ASN1OctetString v1 = null;
            for (final ASN1OctetString s : a1.getRawValues()) {
                if (v1 == null) {
                    v1 = s;
                } else {
                    try {
                        if (matchingRule.compareValues(s, v1) < 0) {
                            v1 = s;
                        }
                    } catch (final LDAPException le) {
                        Debug.debugException(le);
                    }
                }
            }
            ASN1OctetString v2 = null;
            for (final ASN1OctetString s : a2.getRawValues()) {
                if (v2 == null) {
                    v2 = s;
                } else {
                    try {
                        if (matchingRule.compareValues(s, v2) < 0) {
                            v2 = s;
                        }
                    } catch (final LDAPException le) {
                        Debug.debugException(le);
                    }
                }
            }
            try {
                final int value = matchingRule.compareValues(v1, v2);
                if (value != 0) {
                    return value;
                }
            } catch (final LDAPException le) {
                Debug.debugException(le);
            }
        }
    }
    // sort attributes.  Compare the DNs as a last resort.
    try {
        if (parsedDN1 == null) {
            parsedDN1 = e1.getParsedDN();
        }
        if (parsedDN2 == null) {
            parsedDN2 = e2.getParsedDN();
        }
        return parsedDN1.compareTo(parsedDN2);
    } catch (final LDAPException le) {
        Debug.debugException(le);
        final String lowerDN1 = StaticUtils.toLowerCase(e1.getDN());
        final String lowerDN2 = StaticUtils.toLowerCase(e2.getDN());
        return lowerDN1.compareTo(lowerDN2);
    }
}
Also used : ASN1OctetString(com.unboundid.asn1.ASN1OctetString) SortKey(com.unboundid.ldap.sdk.controls.SortKey) ASN1OctetString(com.unboundid.asn1.ASN1OctetString) MatchingRule(com.unboundid.ldap.matchingrules.MatchingRule)

Aggregations

MatchingRule (com.unboundid.ldap.matchingrules.MatchingRule)19 ASN1OctetString (com.unboundid.asn1.ASN1OctetString)18 NotNull (com.unboundid.util.NotNull)12 CaseIgnoreStringMatchingRule (com.unboundid.ldap.matchingrules.CaseIgnoreStringMatchingRule)11 Attribute (com.unboundid.ldap.sdk.Attribute)8 LDAPException (com.unboundid.ldap.sdk.LDAPException)8 GeneralizedTimeMatchingRule (com.unboundid.ldap.matchingrules.GeneralizedTimeMatchingRule)7 RDN (com.unboundid.ldap.sdk.RDN)7 ArrayList (java.util.ArrayList)5 Date (java.util.Date)5 BooleanMatchingRule (com.unboundid.ldap.matchingrules.BooleanMatchingRule)4 OctetStringMatchingRule (com.unboundid.ldap.matchingrules.OctetStringMatchingRule)4 DN (com.unboundid.ldap.sdk.DN)4 DistinguishedNameMatchingRule (com.unboundid.ldap.matchingrules.DistinguishedNameMatchingRule)3 IntegerMatchingRule (com.unboundid.ldap.matchingrules.IntegerMatchingRule)3 ASN1Exception (com.unboundid.asn1.ASN1Exception)2 LDAPMessage (com.unboundid.ldap.protocol.LDAPMessage)2 ChangeLogEntry (com.unboundid.ldap.sdk.ChangeLogEntry)2 Control (com.unboundid.ldap.sdk.Control)2 Entry (com.unboundid.ldap.sdk.Entry)2