com.unboundid.ldap.sdk.controls.MatchedValuesRequestControl Maven / Gradle / Ivy
                 Go to download
                
        
                    Show more of this group  Show more artifacts with this name
Show all versions of unboundid-ldapsdk-commercial-edition Show documentation
                Show all versions of unboundid-ldapsdk-commercial-edition Show documentation
      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 Commercial Edition of the LDAP SDK, which includes
      all of the general-purpose functionality contained in the Standard
      Edition, plus additional functionality specific to UnboundID server
      products.
    
                
            /*
 * Copyright 2008-2016 UnboundID Corp.
 * All Rights Reserved.
 */
/*
 * Copyright (C) 2008-2016 UnboundID Corp.
 *
 * 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.controls;
import com.unboundid.asn1.ASN1Element;
import com.unboundid.asn1.ASN1OctetString;
import com.unboundid.asn1.ASN1Sequence;
import com.unboundid.ldap.sdk.Control;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.util.NotMutable;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;
import static com.unboundid.ldap.sdk.controls.ControlMessages.*;
import static com.unboundid.util.Debug.*;
import static com.unboundid.util.Validator.*;
/**
 * This class provides an implementation of the matched values request control
 * as defined in RFC 3876.  It
 * should only be used with a search request, in which case it indicates that
 * only attribute values matching at least one of the provided
 * {@link MatchedValuesFilter}s should be included in matching entries.  That
 * is, this control may be used to restrict the set of values included in the
 * entries that are returned.  This is particularly useful for multivalued
 * attributes with a large number of values when only a small number of values
 * are of interest to the client.
 * 
 * There are no corresponding response controls included in the search result
 * entry, search result reference, or search result done messages returned for
 * the associated search request.
 * 
 * Example
 * The following example demonstrates the use of the matched values request
 * control.  It will cause only values of the "{@code description}" attribute
 * to be returned in which those values start with the letter f:
 * 
 * // Ensure that a test user has multiple description values.
 * LDAPResult modifyResult = connection.modify(
 *      "uid=test.user,ou=People,dc=example,dc=com",
 *      new Modification(ModificationType.REPLACE,
 *           "description", // Attribute name
 *           "first", "second", "third", "fourth")); // Attribute values.
 * assertResultCodeEquals(modifyResult, ResultCode.SUCCESS);
 *
 * // Perform a search to retrieve the test user entry without using the
 * // matched values request control.  This should return all four description
 * // values.
 * SearchRequest searchRequest = new SearchRequest(
 *      "uid=test.user,ou=People,dc=example,dc=com", // Base DN
 *      SearchScope.BASE, // Scope
 *      Filter.createPresenceFilter("objectClass"), // Filter
 *      "description"); // Attributes to return.
 * SearchResultEntry entryRetrievedWithoutControl =
 *      connection.searchForEntry(searchRequest);
 * Attribute fullDescriptionAttribute =
 *      entryRetrievedWithoutControl.getAttribute("description");
 * int numFullDescriptionValues = fullDescriptionAttribute.size();
 *
 * // Update the search request to include a matched values control that will
 * // only return values that start with the letter "f".  In our test entry,
 * // this should just match two values ("first" and "fourth").
 * searchRequest.addControl(new MatchedValuesRequestControl(
 *      MatchedValuesFilter.createSubstringFilter("description", // Attribute
 *           "f", // subInitial component
 *           null, // subAny components
 *           null))); // subFinal component
 * SearchResultEntry entryRetrievedWithControl =
 *      connection.searchForEntry(searchRequest);
 * Attribute partialDescriptionAttribute =
 *      entryRetrievedWithControl.getAttribute("description");
 * int numPartialDescriptionValues = partialDescriptionAttribute.size();
 * 
 */
@NotMutable()
@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
public final class MatchedValuesRequestControl
       extends Control
{
  /**
   * The OID (1.2.826.0.1.3344810.2.3) for the matched values request control.
   */
  public static final String MATCHED_VALUES_REQUEST_OID =
       "1.2.826.0.1.3344810.2.3";
  /**
   * The serial version UID for this serializable class.
   */
  private static final long serialVersionUID = 6799850686547208774L;
  // The set of matched values filters for this control.
  private final MatchedValuesFilter[] filters;
  /**
   * Creates a new matched values request control with the provided set of
   * filters.  It will not be be marked as critical.
   *
   * @param  filters  The set of filters to use for this control.  At least one
   *                  filter must be provided.
   */
  public MatchedValuesRequestControl(final MatchedValuesFilter... filters)
  {
    this(false, filters);
  }
  /**
   * Creates a new matched values request control with the provided criticality
   * and set of filters.
   *
   * @param  isCritical  Indicates whether this control should be marked
   *                     critical.
   * @param  filters     The set of filters to use for this control.  At least
   *                     one filter must be provided.
   */
  public MatchedValuesRequestControl(final boolean isCritical,
                                     final MatchedValuesFilter... filters)
  {
    super(MATCHED_VALUES_REQUEST_OID, isCritical,  encodeValue(filters));
    this.filters = filters;
  }
  /**
   * Creates a new matched values request control which is decoded from the
   * provided generic control.
   *
   * @param  control  The generic control to be decoded as a matched values
   *                  request control.
   *
   * @throws  LDAPException  If the provided control cannot be decoded as a
   *                         matched values request control.
   */
  public MatchedValuesRequestControl(final Control control)
         throws LDAPException
  {
    super(control);
    final ASN1OctetString value = control.getValue();
    if (value == null)
    {
      throw new LDAPException(ResultCode.DECODING_ERROR,
                              ERR_MV_REQUEST_NO_VALUE.get());
    }
    try
    {
      final ASN1Element valueElement = ASN1Element.decode(value.getValue());
      final ASN1Element[] filterElements =
           ASN1Sequence.decodeAsSequence(valueElement).elements();
      filters = new MatchedValuesFilter[filterElements.length];
      for (int i=0; i < filterElements.length; i++)
      {
        filters[i] = MatchedValuesFilter.decode(filterElements[i]);
      }
    }
    catch (Exception e)
    {
      debugException(e);
      throw new LDAPException(ResultCode.DECODING_ERROR,
                              ERR_MV_REQUEST_CANNOT_DECODE.get(e), e);
    }
  }
  /**
   * Encodes the provided set of filters into a value appropriate for use with
   * the matched values control.
   *
   * @param  filters  The set of filters to include in the value.  It must not
   *                  be {@code null} or empty.
   *
   * @return  The ASN.1 octet string containing the encoded control value.
   */
  private static ASN1OctetString encodeValue(
                                      final MatchedValuesFilter[] filters)
  {
    ensureNotNull(filters);
    ensureTrue(filters.length > 0,
               "MatchedValuesRequestControl.filters must not be empty.");
    final ASN1Element[] elements = new ASN1Element[filters.length];
    for (int i=0; i < filters.length; i++)
    {
      elements[i] = filters[i].encode();
    }
    return new ASN1OctetString(new ASN1Sequence(elements).encode());
  }
  /**
   * Retrieves the set of filters for this matched values request control.
   *
   * @return  The set of filters for this matched values request control.
   */
  public MatchedValuesFilter[] getFilters()
  {
    return filters;
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public String getControlName()
  {
    return INFO_CONTROL_NAME_MATCHED_VALUES_REQUEST.get();
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void toString(final StringBuilder buffer)
  {
    buffer.append("MatchedValuesRequestControl(filters={");
    for (int i=0; i < filters.length; i++)
    {
      if (i > 0)
      {
        buffer.append(", ");
      }
      buffer.append('\'');
      filters[i].toString(buffer);
      buffer.append('\'');
    }
    buffer.append("}, isCritical=");
    buffer.append(isCritical());
    buffer.append(')');
  }
}
     © 2015 - 2025 Weber Informatics LLC | Privacy Policy