001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.protocols.ldap; 028 import org.opends.messages.Message; 029 030 031 032 import java.util.ArrayList; 033 034 import org.opends.server.protocols.asn1.ASN1Element; 035 import org.opends.server.protocols.asn1.ASN1Exception; 036 import org.opends.server.protocols.asn1.ASN1OctetString; 037 import org.opends.server.protocols.asn1.ASN1Sequence; 038 import org.opends.server.types.DebugLogLevel; 039 import org.opends.server.types.LDAPException; 040 041 import static org.opends.server.loggers.debug.DebugLogger.*; 042 import org.opends.server.loggers.debug.DebugTracer; 043 import static org.opends.messages.ProtocolMessages.*; 044 import static org.opends.server.protocols.ldap.LDAPConstants.*; 045 import static org.opends.server.protocols.ldap.LDAPResultCode.*; 046 import static org.opends.server.util.ServerConstants.*; 047 import static org.opends.server.util.StaticUtils.*; 048 049 050 051 /** 052 * This class defines the structures and methods for an LDAP intermediate 053 * response protocol op, which is used to provide information to a client before 054 * the final response for an operation. 055 */ 056 public class IntermediateResponseProtocolOp 057 extends ProtocolOp 058 { 059 /** 060 * The tracer object for the debug logger. 061 */ 062 private static final DebugTracer TRACER = getTracer(); 063 064 // The value for this intermediate response. 065 private ASN1OctetString value; 066 067 // The OID for this intermediate response. 068 private String oid; 069 070 071 072 /** 073 * Creates a new intermediate protocol op with the specified OID and no 074 * value. 075 * 076 * @param oid The OID for this intermediate response. 077 */ 078 public IntermediateResponseProtocolOp(String oid) 079 { 080 this.oid = oid; 081 this.value = null; 082 } 083 084 085 086 /** 087 * Creates a new intermediate response protocol op with the specified OID and 088 * value. 089 * 090 * @param oid The OID for this intermediate response. 091 * @param value The value for this intermediate response. 092 */ 093 public IntermediateResponseProtocolOp(String oid, ASN1OctetString value) 094 { 095 this.oid = oid; 096 this.value = value; 097 } 098 099 100 101 /** 102 * Retrieves the OID for this intermediate response. 103 * 104 * @return The OID for this intermediate response, or <CODE>null</CODE> if 105 * there is no OID. 106 */ 107 public String getOID() 108 { 109 return oid; 110 } 111 112 113 114 /** 115 * Specifies the OID for this intermediate response. 116 * 117 * @param oid The OID for this intermediate response. 118 */ 119 public void setOID(String oid) 120 { 121 this.oid = oid; 122 } 123 124 125 126 /** 127 * Retrieves the value for this intermediate response. 128 * 129 * @return The value for this intermediate response, or <CODE>null</CODE> if 130 * there is no value. 131 */ 132 public ASN1OctetString getValue() 133 { 134 return value; 135 } 136 137 138 139 /** 140 * Specifies the value for this intermediate response. 141 * 142 * @param value The value for this intermediate response. 143 */ 144 public void setValue(ASN1OctetString value) 145 { 146 this.value = value; 147 } 148 149 150 151 /** 152 * Retrieves the BER type for this protocol op. 153 * 154 * @return The BER type for this protocol op. 155 */ 156 public byte getType() 157 { 158 return OP_TYPE_INTERMEDIATE_RESPONSE; 159 } 160 161 162 163 /** 164 * Retrieves the name for this protocol op type. 165 * 166 * @return The name for this protocol op type. 167 */ 168 public String getProtocolOpName() 169 { 170 return "Intermediate Response"; 171 } 172 173 174 175 /** 176 * Encodes this protocol op to an ASN.1 element suitable for including in an 177 * LDAP message. 178 * 179 * @return The ASN.1 element containing the encoded protocol op. 180 */ 181 public ASN1Element encode() 182 { 183 ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2); 184 185 if (oid != null) 186 { 187 elements.add(new ASN1OctetString(TYPE_INTERMEDIATE_RESPONSE_OID, oid)); 188 } 189 190 if (value != null) 191 { 192 value.setType(TYPE_INTERMEDIATE_RESPONSE_VALUE); 193 elements.add(value); 194 } 195 196 return new ASN1Sequence(OP_TYPE_INTERMEDIATE_RESPONSE, elements); 197 } 198 199 200 201 /** 202 * Decodes the provided ASN.1 element as an LDAP intermediate response 203 * protocol op. 204 * 205 * @param element The ASN.1 element to be decoded. 206 * 207 * @return The decoded intermediate response protocol op. 208 * 209 * @throws LDAPException If a problem occurs while attempting to decode the 210 * provided ASN.1 element as an LDAP intermediate 211 * response protocol op. 212 */ 213 public static IntermediateResponseProtocolOp 214 decodeIntermediateResponse(ASN1Element element) 215 throws LDAPException 216 { 217 ArrayList<ASN1Element> elements; 218 try 219 { 220 elements = element.decodeAsSequence().elements(); 221 } 222 catch (Exception e) 223 { 224 if (debugEnabled()) 225 { 226 TRACER.debugCaught(DebugLogLevel.ERROR, e); 227 } 228 229 Message message = 230 ERR_LDAP_INTERMEDIATE_RESPONSE_DECODE_SEQUENCE.get(String.valueOf(e)); 231 throw new LDAPException(PROTOCOL_ERROR, message, e); 232 } 233 234 235 int numElements = elements.size(); 236 if (numElements > 2) 237 { 238 Message message = 239 ERR_LDAP_INTERMEDIATE_RESPONSE_DECODE_INVALID_ELEMENT_COUNT. 240 get(numElements); 241 throw new LDAPException(PROTOCOL_ERROR, message); 242 } 243 244 245 String oid = null; 246 ASN1OctetString value = null; 247 248 if (elements.size() == 1) 249 { 250 ASN1Element e = elements.get(0); 251 252 switch (e.getType()) 253 { 254 case TYPE_INTERMEDIATE_RESPONSE_OID: 255 try 256 { 257 oid = e.decodeAsOctetString().stringValue(); 258 } 259 catch (ASN1Exception ae) 260 { 261 if (debugEnabled()) 262 { 263 TRACER.debugCaught(DebugLogLevel.ERROR, ae); 264 } 265 266 Message message = ERR_LDAP_INTERMEDIATE_RESPONSE_CANNOT_DECODE_OID. 267 get(ae.getMessage()); 268 throw new LDAPException(PROTOCOL_ERROR, message); 269 } 270 break; 271 case TYPE_INTERMEDIATE_RESPONSE_VALUE: 272 try 273 { 274 value = e.decodeAsOctetString(); 275 } 276 catch (ASN1Exception ae) 277 { 278 if (debugEnabled()) 279 { 280 TRACER.debugCaught(DebugLogLevel.ERROR, ae); 281 } 282 283 Message message = 284 ERR_LDAP_INTERMEDIATE_RESPONSE_CANNOT_DECODE_VALUE. 285 get(ae.getMessage()); 286 throw new LDAPException(PROTOCOL_ERROR, message); 287 } 288 break; 289 default: 290 Message message = ERR_LDAP_INTERMEDIATE_RESPONSE_INVALID_ELEMENT_TYPE. 291 get(byteToHex(e.getType())); 292 throw new LDAPException(PROTOCOL_ERROR, message); 293 } 294 } 295 else if (elements.size() == 2) 296 { 297 try 298 { 299 oid = elements.get(0).decodeAsOctetString().stringValue(); 300 } 301 catch (ASN1Exception ae) 302 { 303 if (debugEnabled()) 304 { 305 TRACER.debugCaught(DebugLogLevel.ERROR, ae); 306 } 307 308 Message message = ERR_LDAP_INTERMEDIATE_RESPONSE_CANNOT_DECODE_OID.get( 309 ae.getMessage()); 310 throw new LDAPException(PROTOCOL_ERROR, message); 311 } 312 313 try 314 { 315 value = elements.get(1).decodeAsOctetString(); 316 } 317 catch (ASN1Exception ae) 318 { 319 if (debugEnabled()) 320 { 321 TRACER.debugCaught(DebugLogLevel.ERROR, ae); 322 } 323 324 Message message = ERR_LDAP_INTERMEDIATE_RESPONSE_CANNOT_DECODE_OID.get( 325 ae.getMessage()); 326 throw new LDAPException(PROTOCOL_ERROR, message); 327 } 328 } 329 330 331 return new IntermediateResponseProtocolOp(oid, value); 332 } 333 334 335 336 /** 337 * Appends a string representation of this LDAP protocol op to the provided 338 * buffer. 339 * 340 * @param buffer The buffer to which the string should be appended. 341 */ 342 public void toString(StringBuilder buffer) 343 { 344 buffer.append("IntermediateResponse(oid="); 345 buffer.append(String.valueOf(oid)); 346 347 if (value != null) 348 { 349 buffer.append(", value="); 350 value.toString(buffer); 351 } 352 353 buffer.append(")"); 354 } 355 356 357 358 /** 359 * Appends a multi-line string representation of this LDAP protocol op to the 360 * provided buffer. 361 * 362 * @param buffer The buffer to which the information should be appended. 363 * @param indent The number of spaces from the margin that the lines should 364 * be indented. 365 */ 366 public void toString(StringBuilder buffer, int indent) 367 { 368 StringBuilder indentBuf = new StringBuilder(indent); 369 for (int i=0 ; i < indent; i++) 370 { 371 indentBuf.append(' '); 372 } 373 374 buffer.append(indentBuf); 375 buffer.append("Intermediate Response"); 376 buffer.append(EOL); 377 378 if (oid != null) 379 { 380 buffer.append(indentBuf); 381 buffer.append(" OID: "); 382 buffer.append(oid); 383 buffer.append(EOL); 384 } 385 386 if (value != null) 387 { 388 buffer.append(indentBuf); 389 buffer.append(" Value:"); 390 buffer.append(EOL); 391 value.toString(buffer, indent+4); 392 } 393 } 394 } 395