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-2015 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 /** 069 * ControlDecoder implementation to decode this control from a ByteString. 070 */ 071 private static final class Decoder 072 implements ControlDecoder<ServerSideSortResponseControl> 073 { 074 /** {@inheritDoc} */ 075 public ServerSideSortResponseControl decode(boolean isCritical, 076 ByteString value) 077 throws DirectoryException 078 { 079 if (value == null) 080 { 081 LocalizableMessage message = INFO_SORTRES_CONTROL_NO_VALUE.get(); 082 throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message); 083 } 084 085 ASN1Reader reader = ASN1.getReader(value); 086 try 087 { 088 reader.readStartSequence(); 089 int resultCode = (int)reader.readInteger(); 090 091 String attributeType = null; 092 if(reader.hasNextElement()) 093 { 094 attributeType = reader.readOctetStringAsString(); 095 } 096 097 return new ServerSideSortResponseControl(isCritical, 098 resultCode, 099 attributeType); 100 } 101 catch (Exception e) 102 { 103 LocalizableMessage message = 104 INFO_SORTRES_CONTROL_CANNOT_DECODE_VALUE.get( 105 getExceptionMessage(e)); 106 throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e); 107 } 108 } 109 110 public String getOID() 111 { 112 return OID_SERVER_SIDE_SORT_RESPONSE_CONTROL; 113 } 114 115 } 116 117 /** 118 * The Control Decoder that can be used to decode this control. 119 */ 120 public static final ControlDecoder<ServerSideSortResponseControl> DECODER = 121 new Decoder(); 122 123 /** 124 * The BER type to use when encoding the attribute type element. 125 */ 126 private static final byte TYPE_ATTRIBUTE_TYPE = (byte) 0x80; 127 128 129 130 /** The result code for the sort result. */ 131 private int resultCode; 132 133 /** The attribute type for the sort result. */ 134 private String attributeType; 135 136 137 138 /** 139 * Creates a new server-side sort response control based on the provided 140 * result code and attribute type. 141 * 142 * @param resultCode The result code for the sort result. 143 * @param attributeType The attribute type for the sort result (or 144 * {@code null} if there is none). 145 */ 146 public ServerSideSortResponseControl(int resultCode, String attributeType) 147 { 148 this(false, resultCode, attributeType); 149 } 150 151 152 153 /** 154 * Creates a new server-side sort response control with the provided 155 * information. 156 * 157 * @param isCritical Indicates whether support for this control should be 158 * considered a critical part of the server processing. 159 * @param resultCode The result code for the sort result. 160 * @param attributeType The attribute type for the sort result. 161 */ 162 public ServerSideSortResponseControl(boolean isCritical, 163 int resultCode, 164 String attributeType) 165 { 166 super(OID_SERVER_SIDE_SORT_RESPONSE_CONTROL, isCritical); 167 168 this.resultCode = resultCode; 169 this.attributeType = attributeType; 170 } 171 172 173 174 /** 175 * Retrieves the result code for this sort result. 176 * 177 * @return The result code for this sort result. 178 */ 179 public int getResultCode() 180 { 181 return resultCode; 182 } 183 184 185 186 /** 187 * Retrieves the attribute type for this sort result. 188 * 189 * @return The attribute type for this sort result, or {@code null} if there 190 * is none. 191 */ 192 public String getAttributeType() 193 { 194 return attributeType; 195 } 196 197 198 199 /** 200 * Writes this control's value to an ASN.1 writer. The value (if any) must be 201 * written as an ASN1OctetString. 202 * 203 * @param writer The ASN.1 writer to use. 204 * @throws IOException If a problem occurs while writing to the stream. 205 */ 206 @Override 207 protected void writeValue(ASN1Writer writer) throws IOException { 208 writer.writeStartSequence(ASN1.UNIVERSAL_OCTET_STRING_TYPE); 209 210 writer.writeStartSequence(); 211 writer.writeEnumerated(resultCode); 212 if (attributeType != null) 213 { 214 writer.writeOctetString(TYPE_ATTRIBUTE_TYPE, attributeType); 215 } 216 writer.writeEndSequence(); 217 218 writer.writeEndSequence(); 219 } 220 221 222 223 /** 224 * Appends a string representation of this server-side sort response control 225 * to the provided buffer. 226 * 227 * @param buffer The buffer to which the information should be appended. 228 */ 229 @Override 230 public void toString(StringBuilder buffer) 231 { 232 buffer.append("ServerSideSortResponseControl(resultCode="); 233 buffer.append(resultCode); 234 235 if (attributeType != null) 236 { 237 buffer.append(", attributeType="); 238 buffer.append(attributeType); 239 } 240 241 buffer.append(")"); 242 } 243} 244