/* * Sun Public License * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is available at http://www.sun.com/ * * The Original Code is the SLAMD Distributed Load Generation Engine. * The Initial Developer of the Original Code is Neil A. Wilson. * Portions created by Neil A. Wilson are Copyright (C) 2004-2010. * Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): Neil A. Wilson */ package com.slamd.tools.ldapdecoder.protocol; import com.slamd.asn1.ASN1Element; import com.slamd.asn1.ASN1Enumerated; import com.slamd.asn1.ASN1OctetString; import com.slamd.asn1.ASN1Sequence; /** * This class defines the server-side sort response control, which is included * in the search result done message that the server sends to the client after * performing a search that included sorting. * * * @author Neil A. Wilson */ public class ServerSortResponseControl extends LDAPControl { /** * The OID of the server sort response control. */ public static final String SERVER_SORT_RESPONSE_CONTROL_OID = "1.2.840.113556.1.4.474"; /** * The ASN.1 type that will be used if an attribute type is included in the * sort response control. */ public static final byte TYPE_ATTRIBUTE_TYPE = (byte) 0x80; // The result code for the sort operation. private int resultCode; // The attribute type associated with the sort key that caused the first // error in the sorting process. private String attributeType; /** * Creates a new server sort response control with the provided information. * * @param isCritical Indicates whether this control should be marked * critical. * @param resultCode The result code for the sort operation. */ public ServerSortResponseControl(boolean isCritical, int resultCode) { super(SERVER_SORT_RESPONSE_CONTROL_OID, isCritical, encodeValue(resultCode, null)); this.resultCode = resultCode; this.attributeType = null; } /** * Creates a new server sort response control with the provided information. * * @param isCritical Indicates whether this control should be marked * critical. * @param resultCode The result code for the sort operation. * @param attributeType The attribute associated with the sort key that * caused the first error in the sorting process. */ public ServerSortResponseControl(boolean isCritical, int resultCode, String attributeType) { super(SERVER_SORT_RESPONSE_CONTROL_OID, isCritical, encodeValue(resultCode, attributeType)); this.resultCode = resultCode; this.attributeType = attributeType; } /** * Creates a new server sort response control by decoding the provided value. * * @param isCritical Indicates whether this control should be marked * critical. * @param controlValue The encoded value for this control. * * @throws ProtocolException If a problem occurs while decoding the value * for the control. */ public ServerSortResponseControl(boolean isCritical, ASN1OctetString controlValue) throws ProtocolException { super(SERVER_SORT_RESPONSE_CONTROL_OID, isCritical, controlValue); ASN1Element[] elements; try { byte[] valueBytes = controlValue.getValue(); elements = ASN1Element.decodeAsSequence(valueBytes).getElements(); } catch (Exception e) { throw new ProtocolException("Unable to decode the server sort response " + "control sequence", e); } if ((elements.length < 1) || (elements.length > 2)) { throw new ProtocolException("There must be either 1 or 2 elements in " + "a server sort response control sequence"); } try { resultCode = elements[0].decodeAsEnumerated().getIntValue(); } catch (Exception e) { throw new ProtocolException("Unable to decode result code for server " + "sort response control"); } if (elements.length == 2) { try { attributeType = elements[1].decodeAsOctetString().getStringValue(); } catch (Exception e) { throw new ProtocolException("Unable to decode attribute type for " + "server sort response control"); } } else { attributeType = null; } } /** * Retrieves the result code for the server-side sort operation. * * @return The result code for the server-side sort operation. */ public int getResultCode() { return resultCode; } /** * Retrieves the attribute type for the server-side sort operation. * * @return The attribute type for the server-side sort operation. */ public String getAttributeType() { return attributeType; } /** * Encodes the provided information into an octet string suitable for use as * the value of this control. * * @param resultCode The result code for this server-side sort response. * @param attributeType The attribute type for this server-side sort * response. * * @return The octet string containing the encoded control value. */ public static ASN1OctetString encodeValue(int resultCode, String attributeType) { ASN1Element[] elements; if (attributeType == null) { elements = new ASN1Element[] { new ASN1Enumerated(resultCode) }; } else { elements = new ASN1Element[] { new ASN1Enumerated(resultCode), new ASN1OctetString(TYPE_ATTRIBUTE_TYPE, attributeType) }; } return new ASN1OctetString(new ASN1Sequence(elements).encode()); } /** * Retrieves a string representation of this control with the specified * indent. * * @param indent The number of spaces to indent the output. * * @return A string representation of this control with the specified indent. */ public String toString(int indent) { StringBuilder indentBuf = new StringBuilder(indent); for (int i=0; i < indent; i++) { indentBuf.append(' '); } StringBuilder buffer = new StringBuilder(); buffer.append(indentBuf).append("LDAP Server-Side Sort Response Control"). append(LDAPMessage.EOL); buffer.append(indentBuf).append(" OID: ").append(getControlOID()). append(LDAPMessage.EOL); buffer.append(indentBuf).append(" Criticality: "). append(isCritical()).append(LDAPMessage.EOL); buffer.append(indentBuf).append(" Sort Result Code: "). append(resultCode).append(LDAPMessage.EOL); if (attributeType != null) { buffer.append(indentBuf).append(" Attribute for First Error: "). append(attributeType).append(LDAPMessage.EOL); } return buffer.toString(); } }