001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2008-2009 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2016 ForgeRock AS. 016 */ 017package org.opends.server.controls; 018import org.forgerock.i18n.LocalizableMessage; 019 020 021import java.io.IOException; 022 023import org.forgerock.opendj.io.*; 024import org.opends.server.types.Control; 025import org.opends.server.types.DirectoryException; 026import org.forgerock.opendj.ldap.ByteString; 027import org.forgerock.opendj.ldap.ResultCode; 028 029import static org.opends.messages.ProtocolMessages.*; 030import static org.opends.server.util.ServerConstants.*; 031import static org.opends.server.util.StaticUtils.*; 032 033 034 035/** 036 * This class implements the server-side sort response control as defined in RFC 037 * 2891 section 1.2. The ASN.1 description for the control value is: 038 * <BR><BR> 039 * <PRE> 040 * SortResult ::= SEQUENCE { 041 * sortResult ENUMERATED { 042 * success (0), -- results are sorted 043 * operationsError (1), -- server internal failure 044 * timeLimitExceeded (3), -- timelimit reached before 045 * -- sorting was completed 046 * strongAuthRequired (8), -- refused to return sorted 047 * -- results via insecure 048 * -- protocol 049 * adminLimitExceeded (11), -- too many matching entries 050 * -- for the server to sort 051 * noSuchAttribute (16), -- unrecognized attribute 052 * -- type in sort key 053 * inappropriateMatching (18), -- unrecognized or 054 * -- inappropriate matching 055 * -- rule in sort key 056 * insufficientAccessRights (50), -- refused to return sorted 057 * -- results to this client 058 * busy (51), -- too busy to process 059 * unwillingToPerform (53), -- unable to sort 060 * other (80) 061 * }, 062 * attributeType [0] AttributeDescription OPTIONAL } 063 * </PRE> 064 */ 065public class ServerSideSortResponseControl 066 extends Control 067{ 068 /** ControlDecoder implementation to decode this control from a ByteString. */ 069 private static final class Decoder 070 implements ControlDecoder<ServerSideSortResponseControl> 071 { 072 @Override 073 public ServerSideSortResponseControl decode(boolean isCritical, 074 ByteString value) 075 throws DirectoryException 076 { 077 if (value == null) 078 { 079 LocalizableMessage message = INFO_SORTRES_CONTROL_NO_VALUE.get(); 080 throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message); 081 } 082 083 ASN1Reader reader = ASN1.getReader(value); 084 try 085 { 086 reader.readStartSequence(); 087 int resultCode = (int)reader.readInteger(); 088 089 String attributeType = null; 090 if(reader.hasNextElement()) 091 { 092 attributeType = reader.readOctetStringAsString(); 093 } 094 095 return new ServerSideSortResponseControl(isCritical, 096 resultCode, 097 attributeType); 098 } 099 catch (Exception e) 100 { 101 LocalizableMessage message = 102 INFO_SORTRES_CONTROL_CANNOT_DECODE_VALUE.get( 103 getExceptionMessage(e)); 104 throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e); 105 } 106 } 107 108 @Override 109 public String getOID() 110 { 111 return OID_SERVER_SIDE_SORT_RESPONSE_CONTROL; 112 } 113 114 } 115 116 /** The Control Decoder that can be used to decode this control. */ 117 public static final ControlDecoder<ServerSideSortResponseControl> DECODER = 118 new Decoder(); 119 120 /** The BER type to use when encoding the attribute type element. */ 121 private static final byte TYPE_ATTRIBUTE_TYPE = (byte) 0x80; 122 123 124 125 /** The result code for the sort result. */ 126 private int resultCode; 127 128 /** The attribute type for the sort result. */ 129 private String attributeType; 130 131 132 133 /** 134 * Creates a new server-side sort response control based on the provided 135 * result code and attribute type. 136 * 137 * @param resultCode The result code for the sort result. 138 * @param attributeType The attribute type for the sort result (or 139 * {@code null} if there is none). 140 */ 141 public ServerSideSortResponseControl(int resultCode, String attributeType) 142 { 143 this(false, resultCode, attributeType); 144 } 145 146 147 148 /** 149 * Creates a new server-side sort response control with the provided 150 * information. 151 * 152 * @param isCritical Indicates whether support for this control should be 153 * considered a critical part of the server processing. 154 * @param resultCode The result code for the sort result. 155 * @param attributeType The attribute type for the sort result. 156 */ 157 public ServerSideSortResponseControl(boolean isCritical, 158 int resultCode, 159 String attributeType) 160 { 161 super(OID_SERVER_SIDE_SORT_RESPONSE_CONTROL, isCritical); 162 163 this.resultCode = resultCode; 164 this.attributeType = attributeType; 165 } 166 167 168 169 /** 170 * Retrieves the result code for this sort result. 171 * 172 * @return The result code for this sort result. 173 */ 174 public int getResultCode() 175 { 176 return resultCode; 177 } 178 179 180 181 /** 182 * Retrieves the attribute type for this sort result. 183 * 184 * @return The attribute type for this sort result, or {@code null} if there 185 * is none. 186 */ 187 public String getAttributeType() 188 { 189 return attributeType; 190 } 191 192 193 194 /** 195 * Writes this control's value to an ASN.1 writer. The value (if any) must be 196 * written as an ASN1OctetString. 197 * 198 * @param writer The ASN.1 writer to use. 199 * @throws IOException If a problem occurs while writing to the stream. 200 */ 201 @Override 202 protected void writeValue(ASN1Writer writer) throws IOException { 203 writer.writeStartSequence(ASN1.UNIVERSAL_OCTET_STRING_TYPE); 204 205 writer.writeStartSequence(); 206 writer.writeEnumerated(resultCode); 207 if (attributeType != null) 208 { 209 writer.writeOctetString(TYPE_ATTRIBUTE_TYPE, attributeType); 210 } 211 writer.writeEndSequence(); 212 213 writer.writeEndSequence(); 214 } 215 216 217 218 /** 219 * Appends a string representation of this server-side sort response control 220 * to the provided buffer. 221 * 222 * @param buffer The buffer to which the information should be appended. 223 */ 224 @Override 225 public void toString(StringBuilder buffer) 226 { 227 buffer.append("ServerSideSortResponseControl(resultCode="); 228 buffer.append(resultCode); 229 230 if (attributeType != null) 231 { 232 buffer.append(", attributeType="); 233 buffer.append(attributeType); 234 } 235 236 buffer.append(")"); 237 } 238} 239