All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.unboundid.ldap.sdk.unboundidds.controls.MatchingEntryCountResponseControl Maven / Gradle / Ivy

Go to download

The UnboundID LDAP SDK for Java is a fast, comprehensive, and easy-to-use Java API for communicating with LDAP directory servers and performing related tasks like reading and writing LDIF, encoding and decoding data using base64 and ASN.1 BER, and performing secure communication. This package contains the Standard Edition of the LDAP SDK, which is a complete, general-purpose library for communicating with LDAPv3 directory servers.

There is a newer version: 7.0.2
Show newest version
/*
 * Copyright 2014-2021 Ping Identity Corporation
 * All Rights Reserved.
 */
/*
 * Copyright 2014-2021 Ping Identity Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * Copyright (C) 2014-2021 Ping Identity Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (GPLv2 only)
 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see .
 */
package com.unboundid.ldap.sdk.unboundidds.controls;



import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import com.unboundid.asn1.ASN1Boolean;
import com.unboundid.asn1.ASN1Element;
import com.unboundid.asn1.ASN1Integer;
import com.unboundid.asn1.ASN1Null;
import com.unboundid.asn1.ASN1OctetString;
import com.unboundid.asn1.ASN1Sequence;
import com.unboundid.ldap.sdk.Control;
import com.unboundid.ldap.sdk.DecodeableControl;
import com.unboundid.ldap.sdk.Filter;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.ldap.sdk.SearchResult;
import com.unboundid.util.Debug;
import com.unboundid.util.NotMutable;
import com.unboundid.util.NotNull;
import com.unboundid.util.Nullable;
import com.unboundid.util.StaticUtils;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;
import com.unboundid.util.Validator;

import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*;



/**
 * This class provides a response control that may be used to provide
 * information about the number of entries that match a given set of search
 * criteria.  The control will be included in the search result done message
 * for any successful search operation in which the request contained a matching
 * entry count request control.
 * 
*
* NOTE: This class, and other classes within the * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only * supported for use against Ping Identity, UnboundID, and * Nokia/Alcatel-Lucent 8661 server products. These classes provide support * for proprietary functionality or for external specifications that are not * considered stable or mature enough to be guaranteed to work in an * interoperable way with other types of LDAP servers. *
*
* The matching entry count response control has an OID of * "1.3.6.1.4.1.30221.2.5.37", a criticality of false, and a value with the * following encoding: *
 *   MatchingEntryCountResponse ::= SEQUENCE {
 *        entryCount               CHOICE {
 *             examinedCount            [0] INTEGER,
 *             unexaminedCount          [1] INTEGER,
 *             upperBound               [2] INTEGER,
 *             unknown                  [3] NULL,
 *             ... }
 *        debugInfo                [0] SEQUENCE OF OCTET STRING OPTIONAL,
 *        searchIndexed            [1] BOOLEAN DEFAULT TRUE,
 *        shortCircuited           [2] BOOLEAN OPTIONAL,
 *        fullyIndexed             [3] BOOLEAN OPTIONAL,
 *        candidatesAreInScope     [4] BOOLEAN OPTIONAL,
 *        remainingFilter          [5] Filter OPTIONAL,
 *        ... }
 * 
* * @see MatchingEntryCountRequestControl */ @NotMutable() @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) public final class MatchingEntryCountResponseControl extends Control implements DecodeableControl { /** * The OID (1.3.6.1.4.1.30221.2.5.37) for the matching entry count response * control. */ @NotNull public static final String MATCHING_ENTRY_COUNT_RESPONSE_OID = "1.3.6.1.4.1.30221.2.5.37"; /** * The BER type for the element used to hold the list of debug messages. */ private static final byte TYPE_DEBUG_INFO = (byte) 0xA0; /** * The BER type for the element used to indicate whether the search criteria * is at least partially indexed. */ private static final byte TYPE_SEARCH_INDEXED = (byte) 0x81; /** * The BER type for the element used to indicate whether the server * short-circuited during candidate set processing before evaluating all * elements of the search criteria (the filter and scope). */ private static final byte TYPE_SHORT_CIRCUITED = (byte) 0x82; /** * The BER type for the element used to indicate whether the search criteria * is fully indexed. */ private static final byte TYPE_FULLY_INDEXED = (byte) 0x83; /** * The BER type for the element used to indicate whether all the identified * candidate entries are within the scope of the search. */ private static final byte TYPE_CANDIDATES_ARE_IN_SCOPE = (byte) 0x84; /** * The BER type for the element used to provide the remaining filter for the * search operation, which is the portion of the filter that was determined * to be unindexed, or that was unevaluated if processing short-circuited in * the course of building the candidate set. */ private static final byte TYPE_REMAINING_FILTER = (byte) 0xA5; /** * The serial version UID for this serializable class. */ private static final long serialVersionUID = -7808452580964236458L; // Indicates whether the search criteria is considered at least partially // indexed by the server. private final boolean searchIndexed; // Indicates whether all the identified candidate entries are within the scope // of the search. @Nullable private final Boolean candidatesAreInScope; // Indicates whether the search criteria is considered fully indexed. @Nullable private final Boolean fullyIndexed; // Indicates whether the server short-circuited during candidate set // processing before evaluating all elements of the search criteria (the // filter and scope). @Nullable private final Boolean shortCircuited; // The portion of the filter that was either identified as unindexed or that // was not evaluated in the course of building the candidate set. @Nullable private final Filter remainingFilter; // The count value for this matching entry count response control. private final int countValue; // A list of messages providing debug information about the processing // performed by the server. @NotNull private final List debugInfo; // The count type for this matching entry count response control. @NotNull private final MatchingEntryCountType countType; /** * Creates a new empty control instance that is intended to be used only for * decoding controls via the {@code DecodeableControl} interface. */ MatchingEntryCountResponseControl() { searchIndexed = false; candidatesAreInScope = null; fullyIndexed = null; shortCircuited = null; remainingFilter = null; countValue = -1; countType = null; debugInfo = null; } /** * Creates a new matching entry count response control with the provided * information. * * @param countType The matching entry count type. It must not * be {@code null}. * @param countValue The matching entry count value. It must be * greater than or equal to zero for a count * type of either {@code EXAMINED_COUNT} or * {@code UNEXAMINED_COUNT}. It must be greater * than zero for a count type of * {@code UPPER_BOUND}. It must be -1 for a * count type of {@code UNKNOWN}. * @param searchIndexed Indicates whether the search criteria is * considered at least partially indexed and * could be processed more efficiently than * examining all entries with a full database * scan. * @param shortCircuited Indicates whether the server short-circuited * during candidate set processing before * evaluating all elements of the search * criteria (the filter and scope). This may be * {@code null} if it is not available (e.g., * because extended response data was not * requested). * @param fullyIndexed Indicates whether the search is considered * fully indexed. Note that this may be * {@code false} even if the filter is actually * fully indexed if server index processing * short-circuited before evaluating all * components of the filter. To avoid this, * issue the request control with both fast and * slow short-circuit thresholds set to zero. * This may be {@code null} if this is not * available (e.g., because extended response * data was not requested). * @param candidatesAreInScope Indicates whether all the identified * candidate entries are within the scope of * the search. It may be {@code null} if this * is not available (e.g., because extended * response data was not requested). * @param remainingFilter The portion of the filter that was either * identified as unindexed or that was not * evaluated because processing short-circuited * in the course of building the candidate set. * It may be {@code null} if there is no * remaining filter or if this information is * not available (e.g., because extended * response data was not requested). * @param debugInfo An optional list of messages providing debug * information about the processing performed by * the server. It may be {@code null} or empty * if no debug messages should be included. */ private MatchingEntryCountResponseControl( @NotNull final MatchingEntryCountType countType, final int countValue, final boolean searchIndexed, @Nullable final Boolean shortCircuited, @Nullable final Boolean fullyIndexed, @Nullable final Boolean candidatesAreInScope, @Nullable final Filter remainingFilter, @Nullable final Collection debugInfo) { super(MATCHING_ENTRY_COUNT_RESPONSE_OID, false, encodeValue(countType, countValue, searchIndexed, shortCircuited, fullyIndexed, candidatesAreInScope, remainingFilter, debugInfo)); this.countType = countType; this.countValue = countValue; this.searchIndexed = searchIndexed; this.shortCircuited = shortCircuited; this.fullyIndexed = fullyIndexed; this.candidatesAreInScope = candidatesAreInScope; this.remainingFilter = remainingFilter; if (debugInfo == null) { this.debugInfo = Collections.emptyList(); } else { this.debugInfo = Collections.unmodifiableList(new ArrayList<>(debugInfo)); } } /** * Creates a new matching entry count response control decoded from the given * generic control contents. * * @param oid The OID for the control. * @param isCritical Indicates whether this control should be marked * critical. * @param value The encoded value for the control. * * @throws LDAPException If a problem occurs while attempting to decode the * generic control as a matching entry count response * control. */ public MatchingEntryCountResponseControl(@NotNull final String oid, final boolean isCritical, @Nullable final ASN1OctetString value) throws LDAPException { super(oid, isCritical, value); if (value == null) { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_MATCHING_ENTRY_COUNT_RESPONSE_MISSING_VALUE.get()); } try { final ASN1Element[] elements = ASN1Sequence.decodeAsSequence(value.getValue()).elements(); countType = MatchingEntryCountType.valueOf(elements[0].getType()); if (countType == null) { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_MATCHING_ENTRY_COUNT_RESPONSE_INVALID_COUNT_TYPE.get( StaticUtils.toHex(elements[0].getType()))); } switch (countType) { case EXAMINED_COUNT: case UNEXAMINED_COUNT: countValue = ASN1Integer.decodeAsInteger(elements[0]).intValue(); if (countValue < 0) { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_MATCHING_ENTRY_COUNT_RESPONSE_NEGATIVE_EXACT_COUNT.get()); } break; case UPPER_BOUND: countValue = ASN1Integer.decodeAsInteger(elements[0]).intValue(); if (countValue <= 0) { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_MATCHING_ENTRY_COUNT_RESPONSE_NON_POSITIVE_UPPER_BOUND. get()); } break; case UNKNOWN: default: countValue = -1; break; } boolean decodedSearchIndexed = (countType != MatchingEntryCountType.UNKNOWN); Boolean decodedFullyIndexed = null; Boolean decodedCandidatesAreInScope = null; Boolean decodedShortCircuited = null; Filter decodedRemainingFilter = null; List debugMessages = Collections.emptyList(); for (int i=1; i < elements.length; i++) { switch (elements[i].getType()) { case TYPE_DEBUG_INFO: final ASN1Element[] debugElements = ASN1Sequence.decodeAsSequence(elements[i]).elements(); debugMessages = new ArrayList<>(debugElements.length); for (final ASN1Element e : debugElements) { debugMessages.add( ASN1OctetString.decodeAsOctetString(e).stringValue()); } break; case TYPE_SEARCH_INDEXED: decodedSearchIndexed = ASN1Boolean.decodeAsBoolean(elements[i]).booleanValue(); break; case TYPE_SHORT_CIRCUITED: decodedShortCircuited = ASN1Boolean.decodeAsBoolean(elements[i]).booleanValue(); break; case TYPE_FULLY_INDEXED: decodedFullyIndexed = ASN1Boolean.decodeAsBoolean(elements[i]).booleanValue(); break; case TYPE_CANDIDATES_ARE_IN_SCOPE: decodedCandidatesAreInScope = ASN1Boolean.decodeAsBoolean(elements[i]).booleanValue(); break; case TYPE_REMAINING_FILTER: final ASN1Element filterElement = ASN1Element.decode(elements[i].getValue()); decodedRemainingFilter = Filter.decode(filterElement); break; } } searchIndexed = decodedSearchIndexed; shortCircuited = decodedShortCircuited; fullyIndexed = decodedFullyIndexed; candidatesAreInScope = decodedCandidatesAreInScope; remainingFilter = decodedRemainingFilter; debugInfo = Collections.unmodifiableList(debugMessages); } catch (final LDAPException le) { Debug.debugException(le); throw le; } catch (final Exception e) { Debug.debugException(e); throw new LDAPException(ResultCode.DECODING_ERROR, ERR_GET_BACKEND_SET_ID_RESPONSE_CANNOT_DECODE.get( StaticUtils.getExceptionMessage(e)), e); } } /** * Creates a new matching entry count response control for the case in which * the exact number of matching entries is known. * * @param count The exact number of entries matching the associated * search criteria. It must be greater than or equal to * zero. * @param examined Indicates whether the server examined the entries to * exclude those entries that would not be returned to the * client in a normal search with the same criteria. * @param debugInfo An optional list of messages providing debug information * about the processing performed by the server. It may be * {@code null} or empty if no debug messages should be * included. * * @return The matching entry count response control that was created. */ @NotNull() public static MatchingEntryCountResponseControl createExactCountResponse( final int count, final boolean examined, @Nullable final Collection debugInfo) { return createExactCountResponse(count, examined, true, debugInfo); } /** * Creates a new matching entry count response control for the case in which * the exact number of matching entries is known. * * @param count The exact number of entries matching the associated * search criteria. It must be greater than or equal * to zero. * @param examined Indicates whether the server examined the entries to * exclude those entries that would not be returned to * the client in a normal search with the same * criteria. * @param searchIndexed Indicates whether the search criteria is considered * at least partially indexed and could be processed * more efficiently than examining all entries with a * full database scan. * @param debugInfo An optional list of messages providing debug * information about the processing performed by the * server. It may be {@code null} or empty if no debug * messages should be included. * * @return The matching entry count response control that was created. */ @NotNull() public static MatchingEntryCountResponseControl createExactCountResponse( final int count, final boolean examined, final boolean searchIndexed, @Nullable final Collection debugInfo) { return createExactCountResponse(count, examined, searchIndexed, null, null, null, null, debugInfo); } /** * Creates a new matching entry count response control for the case in which * the exact number of matching entries is known. * * @param count The exact number of entries matching the * associated search criteria. It must be * greater than or equal to zero. * @param examined Indicates whether the server examined the * entries to exclude those entries that would * not be returned to the client in a normal * search with the same criteria. * @param searchIndexed Indicates whether the search criteria is * considered at least partially indexed and * could be processed more efficiently than * examining all entries with a full database * scan. * @param shortCircuited Indicates whether the server short-circuited * during candidate set processing before * evaluating all elements of the search * criteria (the filter and scope). This may be * {@code null} if it is not available (e.g., * because extended response data was not * requested). * @param fullyIndexed Indicates whether the search is considered * fully indexed. Note that this may be * {@code false} even if the filter is actually * fully indexed if server index processing * short-circuited before evaluating all * components of the filter. To avoid this, * issue the request control with both fast and * slow short-circuit thresholds set to zero. * This may be {@code null} if this is not * available (e.g., because extended response * data was not requested). * @param candidatesAreInScope Indicates whether all the identified * candidate entries are within the scope of * the search. It may be {@code null} if this * is not available (e.g., because extended * response data was not requested). * @param remainingFilter The portion of the filter that was either * identified as unindexed or that was not * evaluated because processing short-circuited * in the course of building the candidate set. * It may be {@code null} if there is no * remaining filter or if this information is * not available (e.g., because extended * response data was not requested). * @param debugInfo An optional list of messages providing debug * information about the processing performed by * the server. It may be {@code null} or empty * if no debug messages should be included. * * @return The matching entry count response control that was created. */ @NotNull() public static MatchingEntryCountResponseControl createExactCountResponse( final int count, final boolean examined, final boolean searchIndexed, @Nullable final Boolean shortCircuited, @Nullable final Boolean fullyIndexed, @Nullable final Boolean candidatesAreInScope, @Nullable final Filter remainingFilter, @Nullable final Collection debugInfo) { Validator.ensureTrue(count >= 0); final MatchingEntryCountType countType; if (examined) { countType = MatchingEntryCountType.EXAMINED_COUNT; } else { countType = MatchingEntryCountType.UNEXAMINED_COUNT; } return new MatchingEntryCountResponseControl(countType, count, searchIndexed, shortCircuited, fullyIndexed, candidatesAreInScope, remainingFilter, debugInfo); } /** * Creates a new matching entry count response control for the case in which * the exact number of matching entries is not known, but the server was able * to determine an upper bound on the number of matching entries. This upper * bound count may include entries that do not match the search filter, that * are outside the scope of the search, and/or that match the search criteria * but would not have been returned to the client in a normal search with the * same criteria. * * @param upperBound The upper bound on the number of entries that match the * associated search criteria. It must be greater than * zero. * @param debugInfo An optional list of messages providing debug * information about the processing performed by the * server. It may be {@code null} or empty if no debug * messages should be included. * * @return The matching entry count response control that was created. */ @NotNull() public static MatchingEntryCountResponseControl createUpperBoundResponse( final int upperBound, @Nullable final Collection debugInfo) { return createUpperBoundResponse(upperBound, true, debugInfo); } /** * Creates a new matching entry count response control for the case in which * the exact number of matching entries is not known, but the server was able * to determine an upper bound on the number of matching entries. This upper * bound count may include entries that do not match the search filter, that * are outside the scope of the search, and/or that match the search criteria * but would not have been returned to the client in a normal search with the * same criteria. * * @param upperBound The upper bound on the number of entries that match * the associated search criteria. It must be greater * than zero. * @param searchIndexed Indicates whether the search criteria is considered * at least partially indexed and could be processed * more efficiently than examining all entries with a * full database scan. * @param debugInfo An optional list of messages providing debug * information about the processing performed by the * server. It may be {@code null} or empty if no debug * messages should be included. * * @return The matching entry count response control that was created. */ @NotNull() public static MatchingEntryCountResponseControl createUpperBoundResponse( final int upperBound, final boolean searchIndexed, @Nullable final Collection debugInfo) { return createUpperBoundResponse(upperBound, searchIndexed, null, null, null, null, debugInfo); } /** * Creates a new matching entry count response control for the case in which * the exact number of matching entries is not known, but the server was able * to determine an upper bound on the number of matching entries. This upper * bound count may include entries that do not match the search filter, that * are outside the scope of the search, and/or that match the search criteria * but would not have been returned to the client in a normal search with the * same criteria. * * @param upperBound The upper bound on the number of entries that * match the associated search criteria. It * must be greater than zero. * @param searchIndexed Indicates whether the search criteria is * considered at least partially indexed and * could be processed more efficiently than * examining all entries with a full database * scan. * @param shortCircuited Indicates whether the server short-circuited * during candidate set processing before * evaluating all elements of the search * criteria (the filter and scope). This may be * {@code null} if it is not available (e.g., * because extended response data was not * requested). * @param fullyIndexed Indicates whether the search is considered * fully indexed. Note that this may be * {@code false} even if the filter is actually * fully indexed if server index processing * short-circuited before evaluating all * components of the filter. To avoid this, * issue the request control with both fast and * slow short-circuit thresholds set to zero. * This may be {@code null} if this is not * available (e.g., because extended response * data was not requested). * @param candidatesAreInScope Indicates whether all the identified * candidate entries are within the scope of * the search. It may be {@code null} if this * is not available (e.g., because extended * response data was not requested). * @param remainingFilter The portion of the filter that was either * identified as unindexed or that was not * evaluated because processing short-circuited * in the course of building the candidate set. * It may be {@code null} if there is no * remaining filter or if this information is * not available (e.g., because extended * response data was not requested). * @param debugInfo An optional list of messages providing debug * information about the processing performed by * the server. It may be {@code null} or empty * if no debug messages should be included. * * @return The matching entry count response control that was created. */ @NotNull() public static MatchingEntryCountResponseControl createUpperBoundResponse( final int upperBound, final boolean searchIndexed, @Nullable final Boolean shortCircuited, @Nullable final Boolean fullyIndexed, @Nullable final Boolean candidatesAreInScope, @Nullable final Filter remainingFilter, @Nullable final Collection debugInfo) { Validator.ensureTrue(upperBound > 0); return new MatchingEntryCountResponseControl( MatchingEntryCountType.UPPER_BOUND, upperBound, searchIndexed, shortCircuited, fullyIndexed, candidatesAreInScope, remainingFilter, debugInfo); } /** * Creates a new matching entry count response control for the case in which * the server was unable to make any meaningful determination about the number * of entries matching the search criteria. * * @param debugInfo An optional list of messages providing debug information * about the processing performed by the server. It may be * {@code null} or empty if no debug messages should be * included. * * @return The matching entry count response control that was created. */ @NotNull() public static MatchingEntryCountResponseControl createUnknownCountResponse( @Nullable final Collection debugInfo) { return new MatchingEntryCountResponseControl(MatchingEntryCountType.UNKNOWN, -1, false, null, null, null, null, debugInfo); } /** * Encodes a control value with the provided information. * * @param countType The matching entry count type. It must not * be {@code null}. * @param countValue The matching entry count value. It must be * greater than or equal to zero for a count * type of either {@code EXAMINED_COUNT} or * {@code UNEXAMINED_COUNT}. It must be greater * than zero for a count type of * {@code UPPER_BOUND}. It must be -1 for a * count type of {@code UNKNOWN}. * @param searchIndexed Indicates whether the search criteria is * considered at least partially indexed and * could be processed more efficiently than * examining all entries with a full database * scan. * @param shortCircuited Indicates whether the server short-circuited * during candidate set processing before * evaluating all elements of the search * criteria (the filter and scope). This may be * {@code null} if it is not available (e.g., * because extended response data was not * requested). * @param fullyIndexed Indicates whether the search is considered * fully indexed. Note that this may be * {@code false} even if the filter is actually * fully indexed if server index processing * short-circuited before evaluating all * components of the filter. To avoid this, * issue the request control with both fast and * slow short-circuit thresholds set to zero. * This may be {@code null} if this is not * available (e.g., because extended response * data was not requested). * @param candidatesAreInScope Indicates whether all the identified * candidate entries are within the scope of * the search. It may be {@code null} if this * is not available (e.g., because extended * response data was not requested). * @param remainingFilter The portion of the filter that was either * identified as unindexed or that was not * evaluated because processing short-circuited * in the course of building the candidate set. * It may be {@code null} if there is no * remaining filter or if this information is * not available (e.g., because extended * response data was not requested). * @param debugInfo An optional list of messages providing debug * information about the processing performed by * the server. It may be {@code null} or empty * if no debug messages should be included. * * @return The encoded control value. */ @NotNull() private static ASN1OctetString encodeValue( @NotNull final MatchingEntryCountType countType, final int countValue, final boolean searchIndexed, @Nullable final Boolean shortCircuited, @Nullable final Boolean fullyIndexed, @Nullable final Boolean candidatesAreInScope, @Nullable final Filter remainingFilter, @Nullable final Collection debugInfo) { final ArrayList elements = new ArrayList<>(3); switch (countType) { case EXAMINED_COUNT: case UNEXAMINED_COUNT: case UPPER_BOUND: elements.add(new ASN1Integer(countType.getBERType(), countValue)); break; case UNKNOWN: elements.add(new ASN1Null(countType.getBERType())); break; } if (debugInfo != null) { final ArrayList debugElements = new ArrayList<>(debugInfo.size()); for (final String s : debugInfo) { debugElements.add(new ASN1OctetString(s)); } elements.add(new ASN1Sequence(TYPE_DEBUG_INFO, debugElements)); } if (! searchIndexed) { elements.add(new ASN1Boolean(TYPE_SEARCH_INDEXED, searchIndexed)); } if (shortCircuited != null) { elements.add(new ASN1Boolean(TYPE_SHORT_CIRCUITED, shortCircuited)); } if (fullyIndexed != null) { elements.add(new ASN1Boolean(TYPE_FULLY_INDEXED, fullyIndexed)); } if (candidatesAreInScope != null) { elements.add(new ASN1Boolean(TYPE_CANDIDATES_ARE_IN_SCOPE, candidatesAreInScope)); } if (remainingFilter != null) { elements.add(new ASN1OctetString(TYPE_REMAINING_FILTER, remainingFilter.encode().encode())); } return new ASN1OctetString(new ASN1Sequence(elements).encode()); } /** * Retrieves the matching entry count type for the response control. * * @return The matching entry count type for the response control. */ @NotNull() public MatchingEntryCountType getCountType() { return countType; } /** * Retrieves the matching entry count value for the response control. For a * count type of {@code EXAMINED_COUNT} or {@code UNEXAMINED_COUNT}, this is * the exact number of matching entries. For a count type of * {@code UPPER_BOUND}, this is the maximum number of entries that may match * the search criteria, but it may also include entries that do not match the * criteria. For a count type of {@code UNKNOWN}, this will always be -1. * * @return The exact count or upper bound of the number of entries in the * server that may match the search criteria, or -1 if the server * could not determine the number of matching entries. */ public int getCountValue() { return countValue; } /** * Indicates whether the server considers the search criteria to be indexed * and therefore it could be processed more efficiently than examining all * entries with a full database scan. * * @return {@code true} if the server considers the search criteria to be * indexed, or {@code false} if not. */ public boolean searchIndexed() { return searchIndexed; } /** * Indicates whether the server short-circuited during candidate set * processing before evaluating all elements of the search criteria (the * filter and scope). * * @return {@code Boolean.TRUE} if the server did short-circuit during * candidate set processing before evaluating all elements of the * search criteria, {@code Boolean.FALSE} if the server evaluated all * elements of the search criteria, or {@code null} if this * information is not available (e.g., because extended response data * was not requested). */ @Nullable() public Boolean getShortCircuited() { return shortCircuited; } /** * Indicates whether the server considers the search criteria to be fully * indexed. Note that if the server short-circuited during candidate set * processing before evaluating all search criteria (the filter and scope), * this may be {@code Boolean.FALSE} even if the search is actually completely * indexed. * * @return {@code Boolean.TRUE} if the server considers the search criteria * to be fully indexed, {@code Boolean.FALSE} if the search criteria * is not known to be fully indexed, or {@code null} if this * information is not available (e.g., because extended response data * was not requested). */ @Nullable() public Boolean getFullyIndexed() { return fullyIndexed; } /** * Indicates whether the server can determine that all the identified * candidates are within the scope of the search. Note that even if the * server returns {@code Boolean.FALSE}, it does not necessarily mean that * not all the candidates are within the scope of the search, but just that * the server is not certain that is the case. * * @return {@code Boolean.TRUE} if the server can determine that all the * identified candidates are within the scope of the search, * {@code Boolean.FALSE} if the server cannot determine that all the * identified candidates are within the scope of the search, or * {@code null} if this information is not available (e.g., because * extended response data was not requested). */ @Nullable() public Boolean getCandidatesAreInScope() { return candidatesAreInScope; } /** * Retrieves the portion of the filter that was either identified as not * indexed or that was not evaluated during candidate processing (e.g., * because the server short-circuited processing before examining all filter * components). * * @return The portion of the filter that was either identified as not * indexed or that was not evaluated during candidate processing, or * {@code null} if there was no remaining filter or if this * information is not available (e.g., because extended response data * was not requested). */ @Nullable() public Filter getRemainingFilter() { return remainingFilter; } /** * Retrieves a list of messages with debug information about the processing * performed by the server in the course of obtaining the matching entry * count. These messages are intended to be human-readable rather than * machine-parsable. * * @return A list of messages with debug information about the processing * performed by the server in the course of obtaining the matching * entry count, or an empty list if no debug messages were provided. */ @NotNull() public List getDebugInfo() { return debugInfo; } /** * {@inheritDoc} */ @Override() @NotNull() public MatchingEntryCountResponseControl decodeControl( @NotNull final String oid, final boolean isCritical, @Nullable final ASN1OctetString value) throws LDAPException { return new MatchingEntryCountResponseControl(oid, isCritical, value); } /** * Extracts a matching entry count response control from the provided search * result. * * @param result The search result from which to retrieve the matching entry * count response control. * * @return The matching entry count response control contained in the * provided result, or {@code null} if the result did not contain a * matching entry count response control. * * @throws LDAPException If a problem is encountered while attempting to * decode the matching entry count response control * contained in the provided result. */ @Nullable() public static MatchingEntryCountResponseControl get( @NotNull final SearchResult result) throws LDAPException { final Control c = result.getResponseControl(MATCHING_ENTRY_COUNT_RESPONSE_OID); if (c == null) { return null; } if (c instanceof MatchingEntryCountResponseControl) { return (MatchingEntryCountResponseControl) c; } else { return new MatchingEntryCountResponseControl(c.getOID(), c.isCritical(), c.getValue()); } } /** * {@inheritDoc} */ @Override() @NotNull() public String getControlName() { return INFO_CONTROL_NAME_MATCHING_ENTRY_COUNT_RESPONSE.get(); } /** * {@inheritDoc} */ @Override() public void toString(@NotNull final StringBuilder buffer) { buffer.append("MatchingEntryCountResponseControl(countType='"); buffer.append(countType.name()); buffer.append('\''); switch (countType) { case EXAMINED_COUNT: case UNEXAMINED_COUNT: buffer.append(", count="); buffer.append(countValue); break; case UPPER_BOUND: buffer.append(", upperBound="); buffer.append(countValue); break; } buffer.append(", searchIndexed="); buffer.append(searchIndexed); if (shortCircuited != null) { buffer.append(", shortCircuited="); buffer.append(shortCircuited); } if (fullyIndexed != null) { buffer.append(", fullyIndexed="); buffer.append(fullyIndexed); } if (candidatesAreInScope != null) { buffer.append(", candidatesAreInScope="); buffer.append(candidatesAreInScope); } if (remainingFilter != null) { buffer.append(", remainingFilter='"); remainingFilter.toString(buffer); buffer.append('\''); } if (! debugInfo.isEmpty()) { buffer.append(", debugInfo={"); final Iterator iterator = debugInfo.iterator(); while (iterator.hasNext()) { buffer.append('\''); buffer.append(iterator.next()); buffer.append('\''); if (iterator.hasNext()) { buffer.append(", "); } } buffer.append('}'); } buffer.append(')'); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy