/* * 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 * docs/licenses/cddl.txt * or http://www.opensource.org/licenses/cddl1.php. * 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 * docs/licenses/cddl.txt. 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 * * * Portions Copyright 2013-2023 Ping Identity Corporation */ package com.unboundid.directory.sdk.examples; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import com.unboundid.directory.sdk.common.types.CompletedOperationContext; import com.unboundid.directory.sdk.common.types.CompletedSearchOperationContext; import com.unboundid.directory.sdk.ds.api.ResultCriteria; import com.unboundid.directory.sdk.ds.config.ResultCriteriaConfig; import com.unboundid.directory.sdk.ds.types.DirectoryServerContext; import com.unboundid.ldap.sdk.LDAPException; import com.unboundid.ldap.sdk.ResultCode; import com.unboundid.util.args.ArgumentException; import com.unboundid.util.args.ArgumentParser; import com.unboundid.util.args.IntegerArgument; /** * This class provides a simple example of a result criteria implementation that * may be used to match search operations that returned at least a specified * number of entries. It has one configuration argument: * <UL> * <LI>min-entries-returned -- The minimum number of entries that must have * been returned for a search operation in order for this criteria to be * considered a match. If this is not provided, then a default value of * one will be used.</LI> * </UL> */ public final class ExampleResultCriteria extends ResultCriteria { /** * The name of the argument that will be used to specify the minimum number * of entries that should have been returned. */ private static final String ARG_MIN_ENTRIES = "min-entries-returned"; // The minimum number of entries that should have been returned. private volatile long minEntries = 1L; /** * Creates a new instance of this result criteria. All criteria * implementations must include a default constructor, but any initialization * should generally be done in the {@code initializeResultCriteria} method. */ public ExampleResultCriteria() { // No implementation required. } /** * Retrieves a human-readable name for this extension. * * @return A human-readable name for this extension. */ @Override() public String getExtensionName() { return "Example Result Criteria"; } /** * Retrieves a human-readable description for this extension. Each element * of the array that is returned will be considered a separate paragraph in * generated documentation. * * @return A human-readable description for this extension, or {@code null} * or an empty array if no description should be available. */ @Override() public String[] getExtensionDescription() { return new String[] { "This result criteria serves as an example that may be used to " + "demonstrate the process for creating a third-party result " + "criteria. It will match only search operations in which at " + "least a specified number of entries were returned." }; } /** * Updates the provided argument parser to define any configuration arguments * which may be used by this plugin. The argument parser may also be updated * to define relationships between arguments (e.g., to specify required, * exclusive, or dependent argument sets). * * @param parser The argument parser to be updated with the configuration * arguments which may be used by this plugin. * * @throws ArgumentException If a problem is encountered while updating the * provided argument parser. */ @Override() public void defineConfigArguments(final ArgumentParser parser) throws ArgumentException { // Add an argument that allows you to specify the minimum number of entries // to be returned. final Character shortIdentifier = null; final String longIdentifier = ARG_MIN_ENTRIES; final boolean required = false; final int maxOccurrences = 1; final int lowerBound = 1; final int upperBound = Integer.MAX_VALUE; final int defaultValue = 1; final String placeholder = "{num}"; final String description = "The minimum number of entries that " + "must have been returned for this criteria to be considered a match."; parser.addArgument(new IntegerArgument(shortIdentifier, longIdentifier, required, maxOccurrences, placeholder, description, lowerBound, upperBound, defaultValue)); } /** * Initializes this result criteria. * * @param serverContext A handle to the server context for the server in * which this extension is running. * @param config The general configuration for this result criteria. * @param parser The argument parser which has been initialized from * the configuration for this result criteria. * * @throws LDAPException If a problem occurs while initializing this result * criteria. */ @Override() public void initializeResultCriteria( final DirectoryServerContext serverContext, final ResultCriteriaConfig config, final ArgumentParser parser) throws LDAPException { // Get the argument used to specify the minimum number of entries to return. final IntegerArgument minEntriesArg = (IntegerArgument) parser.getNamedArgument(ARG_MIN_ENTRIES); if (minEntriesArg == null) { minEntries = 1L; } else { minEntries = minEntriesArg.getValue().longValue(); } } /** * {@inheritDoc} */ @Override() public boolean isConfigurationAcceptable( final ResultCriteriaConfig config, final ArgumentParser parser, final List<String> unacceptableReasons) { // No extended validation will be performed by default. return true; } /** * {@inheritDoc} */ @Override() public ResultCode applyConfiguration(final ResultCriteriaConfig config, final ArgumentParser parser, final List<String> adminActionsRequired, final List<String> messages) { // Get the argument used to specify the minimum number of entries to return. final IntegerArgument minEntriesArg = (IntegerArgument) parser.getNamedArgument(ARG_MIN_ENTRIES); if (minEntriesArg == null) { minEntries = 1L; } else { minEntries = minEntriesArg.getValue().longValue(); } return ResultCode.SUCCESS; } /** * Performs any cleanup which may be necessary when this result criteria * is to be taken out of service. */ @Override() public void finalizeResultCriteria() { // No implementation is required. } /** * Indicates whether the provided operation matches the criteria for this * result criteria object. * * @param o The operation for which to make the determination. * * @return {@code true} if the provided operation matches the criteria for * this result criteria object, or {@code false} if not. */ @Override() public boolean matches(final CompletedOperationContext o) { // This method will only be invoked for non-search operations, so it will // never match. return false; } /** * Indicates whether the provided search operation matches the criteria for * this result criteria object. In the default implementation, this method * simply invokes the {@link #matches(CompletedOperationContext)} method, and * therefore it only needs to be overridden if search-specific processing is * needed (e.g., to consider the number of entries or references returned, or * whether the search is unindexed). * * @param o The search operation for which to make the determination. * * @return {@code true} if the provided search operation matches the criteria * for this result criteria object, or {@code false} if not. */ @Override() public boolean matches(final CompletedSearchOperationContext o) { // This method will only be called for search operations, so we only need // to check the number of entries that were returned by the search. return (o.getEntryCount() >= minEntries); } /** * {@inheritDoc} */ @Override() public Map<List<String>,String> getExamplesArgumentSets() { final LinkedHashMap<List<String>,String> exampleMap = new LinkedHashMap<List<String>,String>(1); exampleMap.put( Arrays.asList(ARG_MIN_ENTRIES + "=5"), "Match any search operation that returned at least 5 entries."); return Collections.unmodifiableMap(exampleMap); } }