222 lines · 8.7 KB · Java
RawDownload
/* * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.naming.ldap; import java.io.IOException;import com.sun.jndi.ldap.Ber;import com.sun.jndi.ldap.BerEncoder; /** * Requests that the results of a search operation be sorted by the LDAP server * before being returned. * The sort criteria are specified using an ordered list of one or more sort * keys, with associated sort parameters. * Search results are sorted at the LDAP server according to the parameters * supplied in the sort control and then returned to the requestor. If sorting * is not supported at the server (and the sort control is marked as critical) * then the search operation is not performed and an error is returned. * <p> * The following code sample shows how the class may be used: * <pre> * *     // Open an LDAP association *     LdapContext ctx = new InitialLdapContext(); * *     // Activate sorting *     String sortKey = "cn"; *     ctx.setRequestControls(new Control[]{ *         new SortControl(sortKey, Control.CRITICAL) }); * *     // Perform a search *     NamingEnumeration results = *         ctx.search("", "(objectclass=*)", new SearchControls()); * *     // Iterate over search results *     while (results != null && results.hasMore()) { *         // Display an entry *         SearchResult entry = (SearchResult)results.next(); *         System.out.println(entry.getName()); *         System.out.println(entry.getAttributes()); * *         // Handle the entry's response controls (if any) *         if (entry instanceof HasControls) { *             // ((HasControls)entry).getControls(); *         } *     } *     // Examine the sort control response *     Control[] controls = ctx.getResponseControls(); *     if (controls != null) { *         for (int i = 0; i < controls.length; i++) { *             if (controls[i] instanceof SortResponseControl) { *                 SortResponseControl src = (SortResponseControl)controls[i]; *                 if (! src.isSorted()) { *                     throw src.getException(); *                 } *             } else { *                 // Handle other response controls (if any) *             } *         } *     } * *     // Close the LDAP association *     ctx.close(); *     ... * * </pre> * <p> * This class implements the LDAPv3 Request Control for server-side sorting * as defined in * <a href="http://www.ietf.org/rfc/rfc2891.txt">RFC 2891</a>. * * The control's value has the following ASN.1 definition: * <pre> * *     SortKeyList ::= SEQUENCE OF SEQUENCE { *         attributeType     AttributeDescription, *         orderingRule  [0] MatchingRuleId OPTIONAL, *         reverseOrder  [1] BOOLEAN DEFAULT FALSE } * * </pre> * * @since 1.5 * @see SortKey * @see SortResponseControl * @author Vincent Ryan */final public class SortControl extends BasicControl {     /**     * The server-side sort control's assigned object identifier     * is 1.2.840.113556.1.4.473.     */    public static final String OID = "1.2.840.113556.1.4.473";     private static final long serialVersionUID = -1965961680233330744L;     /**     * Constructs a control to sort on a single attribute in ascending order.     * Sorting will be performed using the ordering matching rule defined     * for use with the specified attribute.     *     * @param   sortBy  An attribute ID to sort by.     * @param   criticality     If true then the server must honor the control     *                          and return the search results sorted as     *                          requested or refuse to perform the search.     *                          If false, then the server need not honor the     *                          control.     * @exception IOException If an error was encountered while encoding the     *                        supplied arguments into a control.     */    public SortControl(String sortBy, boolean criticality) throws IOException {         super(OID, criticality, null);        super.value = setEncodedValue(new SortKey[]{ new SortKey(sortBy) });    }     /**     * Constructs a control to sort on a list of attributes in ascending order.     * Sorting will be performed using the ordering matching rule defined     * for use with each of the specified attributes.     *     * @param   sortBy  A non-null list of attribute IDs to sort by.     *                  The list is in order of highest to lowest sort key     *                  precedence.     * @param   criticality     If true then the server must honor the control     *                          and return the search results sorted as     *                          requested or refuse to perform the search.     *                          If false, then the server need not honor the     *                          control.     * @exception IOException If an error was encountered while encoding the     *                        supplied arguments into a control.     */    public SortControl(String[] sortBy, boolean criticality)        throws IOException {         super(OID, criticality, null);        SortKey[] sortKeys = new SortKey[sortBy.length];        for (int i = 0; i < sortBy.length; i++) {            sortKeys[i] = new SortKey(sortBy[i]);        }        super.value = setEncodedValue(sortKeys);    }     /**     * Constructs a control to sort on a list of sort keys.     * Each sort key specifies the sort order and ordering matching rule to use.     *     * @param   sortBy      A non-null list of keys to sort by.     *                      The list is in order of highest to lowest sort key     *                      precedence.     * @param   criticality     If true then the server must honor the control     *                          and return the search results sorted as     *                          requested or refuse to perform the search.     *                          If false, then the server need not honor the     *                          control.     * @exception IOException If an error was encountered while encoding the     *                        supplied arguments into a control.     */    public SortControl(SortKey[] sortBy, boolean criticality)        throws IOException {         super(OID, criticality, null);        super.value = setEncodedValue(sortBy);    }     /*     * Encodes the sort control's value using ASN.1 BER.     * The result includes the BER tag and length for the control's value but     * does not include the control's object identifer and criticality setting.     *     * @param   sortKeys    A non-null list of keys to sort by.     * @return A possibly null byte array representing the ASN.1 BER encoded     *         value of the sort control.     * @exception IOException If a BER encoding error occurs.     */    private byte[] setEncodedValue(SortKey[] sortKeys) throws IOException {         // build the ASN.1 BER encoding        BerEncoder ber = new BerEncoder(30 * sortKeys.length + 10);        String matchingRule;         ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);         for (int i = 0; i < sortKeys.length; i++) {            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);            ber.encodeString(sortKeys[i].getAttributeID(), true); // v3             if ((matchingRule = sortKeys[i].getMatchingRuleID()) != null) {                ber.encodeString(matchingRule, (Ber.ASN_CONTEXT | 0), true);            }            if (! sortKeys[i].isAscending()) {                ber.encodeBoolean(true, (Ber.ASN_CONTEXT | 1));            }            ber.endSeq();        }        ber.endSeq();         return ber.getTrimmedBuf();    }}