UnboundID Server SDK

Ping Identity
UnboundID Server SDK Documentation

ExampleResultCriteria.java

/*
 * 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);
  }
}