package com.hwlcn.ldap.ldap.sdk.controls; import com.hwlcn.ldap.asn1.ASN1Element; import com.hwlcn.ldap.asn1.ASN1OctetString; import com.hwlcn.ldap.asn1.ASN1Sequence; import com.hwlcn.ldap.ldap.sdk.Control; import com.hwlcn.ldap.ldap.sdk.LDAPException; import com.hwlcn.ldap.ldap.sdk.ResultCode; import com.hwlcn.core.annotation.NotMutable; import com.hwlcn.core.annotation.ThreadSafety; import com.hwlcn.ldap.util.ThreadSafetyLevel; import static com.hwlcn.ldap.ldap.sdk.controls.ControlMessages.*; import static com.hwlcn.ldap.util.Debug.*; import static com.hwlcn.ldap.util.Validator.*; /** * This class provides an implementation of the matched values request control * as defined in <A HREF="http://www.ietf.org/rfc/rfc3876.txt">RFC 3876</A>. 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 com.hwlcn.ldap.ldap.sdk.controls.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. * <BR><BR> * 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. * <BR><BR> * <H2>Example</H2> * The following example demonstrates the use of the matched values request * control. It will cause only values of the "{@code myIntValues}" attribute * to be returned in which those values are greater than or equal to five: * <PRE> * SearchRequest searchRequest = * new SearchRequest("uid=john.doe,ou=People,dc=example,dc=com", * SearchScope.BASE, "(objectClass=*)", "myIntValues"); * searchRequest.addControl(new MatchedValuesRequestControl( * MatchedValuesFilter.createGreaterOrEqualFilter("myIntValues", "5")); * SearchResult result = connection.search(searchRequest); * </PRE> */ @NotMutable() @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) public final class MatchedValuesRequestControl extends Control { public static final String MATCHED_VALUES_REQUEST_OID = "1.2.826.0.1.3344810.2.3"; private static final long serialVersionUID = 6799850686547208774L; private final MatchedValuesFilter[] filters; public MatchedValuesRequestControl(final MatchedValuesFilter... filters) { this(false, filters); } public MatchedValuesRequestControl(final boolean isCritical, final MatchedValuesFilter... filters) { super(MATCHED_VALUES_REQUEST_OID, isCritical, encodeValue(filters)); this.filters = filters; } 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); } } 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()); } public MatchedValuesFilter[] getFilters() { return filters; } @Override() public String getControlName() { return INFO_CONTROL_NAME_MATCHED_VALUES_REQUEST.get(); } @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(')'); } }