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 legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2006-2009 Sun Microsystems, Inc. 025 * Portions Copyright 2014-2015 ForgeRock AS 026 */ 027package org.opends.server.protocols.ldap; 028 029 030import java.util.ArrayList; 031import java.util.Iterator; 032import java.util.List; 033import java.io.IOException; 034 035import org.opends.server.api.ProtocolElement; 036import org.forgerock.opendj.io.*; 037import org.opends.server.types.Control; 038 039import static org.opends.server.protocols.ldap.LDAPConstants. 040 TYPE_CONTROL_SEQUENCE; 041import static org.opends.server.util.ServerConstants.*; 042 043 044/** 045 * This class defines the data structures and methods to use when interacting 046 * with an LDAP message, which is the basic envelope used to hold LDAP requests 047 * and responses. 048 */ 049public class LDAPMessage 050 implements ProtocolElement 051{ 052 /** The set of controls for this LDAP message. */ 053 private List<Control> controls; 054 055 /** The message ID for this LDAP message. */ 056 private final int messageID; 057 058 /** The protocol op for this LDAP message. */ 059 private final ProtocolOp protocolOp; 060 061 062 063 /** 064 * Creates a new LDAP message with the provided message ID and protocol op but 065 * no controls. 066 * 067 * @param messageID The message ID for this LDAP message. 068 * @param protocolOp The protocol op for this LDAP message. 069 */ 070 public LDAPMessage(int messageID, ProtocolOp protocolOp) 071 { 072 this(messageID, protocolOp, null); 073 } 074 075 076 077 /** 078 * Creates a new LDAP message with the provided message ID, protocol op, and 079 * set of controls. 080 * 081 * @param messageID The message ID for this LDAP message. 082 * @param protocolOp The protocol op for this LDAP message. 083 * @param controls The set of controls for this LDAP message. 084 */ 085 public LDAPMessage(int messageID, ProtocolOp protocolOp, 086 List<Control> controls) 087 { 088 this.messageID = messageID; 089 this.protocolOp = protocolOp; 090 this.controls = controls; 091 } 092 093 094 095 /** 096 * Retrieves the message ID for this LDAP message. 097 * 098 * @return The message ID for this LDAP message. 099 */ 100 public int getMessageID() 101 { 102 return messageID; 103 } 104 105 106 107 /** 108 * Retrieves the protocol op for this LDAP message. 109 * 110 * @return The protocol op for this LDAP message. 111 */ 112 public ProtocolOp getProtocolOp() 113 { 114 return protocolOp; 115 } 116 117 118 119 /** 120 * Retrieves the protocol op type for this LDAP message. 121 * 122 * @return The protocol op type for this LDAP message. 123 */ 124 public byte getProtocolOpType() 125 { 126 return protocolOp.getType(); 127 } 128 129 130 131 /** 132 * Retrieves the protocol op name for this LDAP message. 133 * 134 * @return The protocol op name for this LDAP message. 135 */ 136 public String getProtocolOpName() 137 { 138 return protocolOp.getProtocolOpName(); 139 } 140 141 142 143 /** 144 * Retrieves the protocol op for this LDAP message as an abandon request 145 * protocol op. 146 * 147 * @return The protocol op for this LDAP message as an abandon request 148 * protocol op. 149 * 150 * @throws ClassCastException If the protocol op is not an abandon request 151 * protocol op. 152 */ 153 public AbandonRequestProtocolOp getAbandonRequestProtocolOp() 154 throws ClassCastException 155 { 156 return (AbandonRequestProtocolOp) protocolOp; 157 } 158 159 160 161 /** 162 * Retrieves the protocol op for this LDAP message as an add request protocol 163 * op. 164 * 165 * @return The protocol op for this LDAP message as an add request protocol 166 * op. 167 * 168 * @throws ClassCastException If the protocol op is not an add request 169 * protocol op. 170 */ 171 public AddRequestProtocolOp getAddRequestProtocolOp() 172 throws ClassCastException 173 { 174 return (AddRequestProtocolOp) protocolOp; 175 } 176 177 178 179 /** 180 * Retrieves the protocol op for this LDAP message as an add response protocol 181 * op. 182 * 183 * @return The protocol op for this LDAP message as an add response protocol 184 * op. 185 * 186 * @throws ClassCastException If the protocol op is not an add response 187 * protocol op. 188 */ 189 public AddResponseProtocolOp getAddResponseProtocolOp() 190 throws ClassCastException 191 { 192 return (AddResponseProtocolOp) protocolOp; 193 } 194 195 196 197 /** 198 * Retrieves the protocol op for this LDAP message as a bind request 199 * protocol op. 200 * 201 * @return The protocol op for this LDAP message as a bind request 202 * protocol op. 203 * 204 * @throws ClassCastException If the protocol op is not a bind request 205 * protocol op. 206 */ 207 public BindRequestProtocolOp getBindRequestProtocolOp() 208 throws ClassCastException 209 { 210 return (BindRequestProtocolOp) protocolOp; 211 } 212 213 214 215 /** 216 * Retrieves the protocol op for this LDAP message as a bind response 217 * protocol op. 218 * 219 * @return The protocol op for this LDAP message as a bind response 220 * protocol op. 221 * 222 * @throws ClassCastException If the protocol op is not a bind response 223 * protocol op. 224 */ 225 public BindResponseProtocolOp getBindResponseProtocolOp() 226 throws ClassCastException 227 { 228 return (BindResponseProtocolOp) protocolOp; 229 } 230 231 232 233 /** 234 * Retrieves the protocol op for this LDAP message as a compare request 235 * protocol op. 236 * 237 * @return The protocol op for this LDAP message as a compare request 238 * protocol op. 239 * 240 * @throws ClassCastException If the protocol op is not a compare request 241 * protocol op. 242 */ 243 public CompareRequestProtocolOp getCompareRequestProtocolOp() 244 throws ClassCastException 245 { 246 return (CompareRequestProtocolOp) protocolOp; 247 } 248 249 250 251 /** 252 * Retrieves the protocol op for this LDAP message as a compare response 253 * protocol op. 254 * 255 * @return The protocol op for this LDAP message as a compare response 256 * protocol op. 257 * 258 * @throws ClassCastException If the protocol op is not a compare response 259 * protocol op. 260 */ 261 public CompareResponseProtocolOp getCompareResponseProtocolOp() 262 throws ClassCastException 263 { 264 return (CompareResponseProtocolOp) protocolOp; 265 } 266 267 268 269 /** 270 * Retrieves the protocol op for this LDAP message as a delete request 271 * protocol op. 272 * 273 * @return The protocol op for this LDAP message as a delete request 274 * protocol op. 275 * 276 * @throws ClassCastException If the protocol op is not a delete request 277 * protocol op. 278 */ 279 public DeleteRequestProtocolOp getDeleteRequestProtocolOp() 280 throws ClassCastException 281 { 282 return (DeleteRequestProtocolOp) protocolOp; 283 } 284 285 286 287 /** 288 * Retrieves the protocol op for this LDAP message as a delete response 289 * protocol op. 290 * 291 * @return The protocol op for this LDAP message as a delete response 292 * protocol op. 293 * 294 * @throws ClassCastException If the protocol op is not a delete response 295 * protocol op. 296 */ 297 public DeleteResponseProtocolOp getDeleteResponseProtocolOp() 298 throws ClassCastException 299 { 300 return (DeleteResponseProtocolOp) protocolOp; 301 } 302 303 304 305 /** 306 * Retrieves the protocol op for this LDAP message as an extended request 307 * protocol op. 308 * 309 * @return The protocol op for this LDAP message as an extended request 310 * protocol op. 311 * 312 * @throws ClassCastException If the protocol op is not an extended request 313 * protocol op. 314 */ 315 public ExtendedRequestProtocolOp getExtendedRequestProtocolOp() 316 throws ClassCastException 317 { 318 return (ExtendedRequestProtocolOp) protocolOp; 319 } 320 321 322 323 /** 324 * Retrieves the protocol op for this LDAP message as an extended response 325 * protocol op. 326 * 327 * @return The protocol op for this LDAP message as an extended response 328 * protocol op. 329 * 330 * @throws ClassCastException If the protocol op is not an extended response 331 * protocol op. 332 */ 333 public ExtendedResponseProtocolOp getExtendedResponseProtocolOp() 334 throws ClassCastException 335 { 336 return (ExtendedResponseProtocolOp) protocolOp; 337 } 338 339 340 341 /** 342 * Retrieves the protocol op for this LDAP message as a modify request 343 * protocol op. 344 * 345 * @return The protocol op for this LDAP message as a modify request 346 * protocol op. 347 * 348 * @throws ClassCastException If the protocol op is not a modify request 349 * protocol op. 350 */ 351 public ModifyRequestProtocolOp getModifyRequestProtocolOp() 352 throws ClassCastException 353 { 354 return (ModifyRequestProtocolOp) protocolOp; 355 } 356 357 358 359 /** 360 * Retrieves the protocol op for this LDAP message as a modify response 361 * protocol op. 362 * 363 * @return The protocol op for this LDAP message as a modify response 364 * protocol op. 365 * 366 * @throws ClassCastException If the protocol op is not a modify response 367 * protocol op. 368 */ 369 public ModifyResponseProtocolOp getModifyResponseProtocolOp() 370 throws ClassCastException 371 { 372 return (ModifyResponseProtocolOp) protocolOp; 373 } 374 375 376 377 /** 378 * Retrieves the protocol op for this LDAP message as a modify DN request 379 * protocol op. 380 * 381 * @return The protocol op for this LDAP message as a modify DN request 382 * protocol op. 383 * 384 * @throws ClassCastException If the protocol op is not a modify DN request 385 * protocol op. 386 */ 387 public ModifyDNRequestProtocolOp getModifyDNRequestProtocolOp() 388 throws ClassCastException 389 { 390 return (ModifyDNRequestProtocolOp) protocolOp; 391 } 392 393 394 395 /** 396 * Retrieves the protocol op for this LDAP message as a modify DN response 397 * protocol op. 398 * 399 * @return The protocol op for this LDAP message as a modify DN response 400 * protocol op. 401 * 402 * @throws ClassCastException If the protocol op is not a modify DN response 403 * protocol op. 404 */ 405 public ModifyDNResponseProtocolOp getModifyDNResponseProtocolOp() 406 throws ClassCastException 407 { 408 return (ModifyDNResponseProtocolOp) protocolOp; 409 } 410 411 412 413 /** 414 * Retrieves the protocol op for this LDAP message as a search request 415 * protocol op. 416 * 417 * @return The protocol op for this LDAP message as a search request 418 * protocol op. 419 * 420 * @throws ClassCastException If the protocol op is not a search request 421 * protocol op. 422 */ 423 public SearchRequestProtocolOp getSearchRequestProtocolOp() 424 throws ClassCastException 425 { 426 return (SearchRequestProtocolOp) protocolOp; 427 } 428 429 430 431 /** 432 * Retrieves the protocol op for this LDAP message as a search result done 433 * protocol op. 434 * 435 * @return The protocol op for this LDAP message as a search result done 436 * protocol op. 437 * 438 * @throws ClassCastException If the protocol op is not a search result done 439 * protocol op. 440 */ 441 public SearchResultDoneProtocolOp getSearchResultDoneProtocolOp() 442 throws ClassCastException 443 { 444 return (SearchResultDoneProtocolOp) protocolOp; 445 } 446 447 448 449 /** 450 * Retrieves the protocol op for this LDAP message as a search result entry 451 * protocol op. 452 * 453 * @return The protocol op for this LDAP message as a search result entry 454 * protocol op. 455 * 456 * @throws ClassCastException If the protocol op is not a search result 457 * entry protocol op. 458 */ 459 public SearchResultEntryProtocolOp getSearchResultEntryProtocolOp() 460 throws ClassCastException 461 { 462 return (SearchResultEntryProtocolOp) protocolOp; 463 } 464 465 466 467 /** 468 * Retrieves the protocol op for this LDAP message as a search result 469 * reference protocol op. 470 * 471 * @return The protocol op for this LDAP message as a search result reference 472 * protocol op. 473 * 474 * @throws ClassCastException If the protocol op is not a search result 475 * reference protocol op. 476 */ 477 public SearchResultReferenceProtocolOp getSearchResultReferenceProtocolOp() 478 throws ClassCastException 479 { 480 return (SearchResultReferenceProtocolOp) protocolOp; 481 } 482 483 484 485 /** 486 * Retrieves the protocol op for this LDAP message as an unbind request 487 * protocol op. 488 * 489 * @return The protocol op for this LDAP message as an unbind request 490 * protocol op. 491 * 492 * @throws ClassCastException If the protocol op is not an unbind request 493 * protocol op. 494 */ 495 public UnbindRequestProtocolOp getUnbindRequestProtocolOp() 496 throws ClassCastException 497 { 498 return (UnbindRequestProtocolOp) protocolOp; 499 } 500 501 502 503 /** 504 * Retrieves the set of controls for this LDAP message. It may be modified by 505 * the caller. 506 * 507 * @return The set of controls for this LDAP message. 508 */ 509 public List<Control> getControls() 510 { 511 // This method is not thread-safe. 512 if (controls == null) 513 { 514 controls = new ArrayList<>(0); 515 } 516 return controls; 517 } 518 519 /** 520 * Writes this protocol op to an ASN.1 output stream. 521 * 522 * @param stream The ASN.1 output stream to write to. 523 * @throws IOException If a problem occurs while writing to the stream. 524 */ 525 public void write(ASN1Writer stream) throws IOException 526 { 527 stream.writeStartSequence(); 528 stream.writeInteger(messageID); 529 protocolOp.write(stream); 530 531 if(controls != null && !controls.isEmpty()) 532 { 533 stream.writeStartSequence(TYPE_CONTROL_SEQUENCE); 534 for(Control control : controls) 535 { 536 control.write(stream); 537 } 538 stream.writeEndSequence(); 539 } 540 541 stream.writeEndSequence(); 542 } 543 544 545 546 /** 547 * Retrieves the name of the protocol associated with this protocol element. 548 * 549 * @return The name of the protocol associated with this protocol element. 550 */ 551 public String getProtocolElementName() 552 { 553 return "LDAP"; 554 } 555 556 557 558 /** 559 * Retrieves a string representation of this LDAP message. 560 * 561 * @return A string representation of this LDAP message. 562 */ 563 @Override 564 public String toString() 565 { 566 StringBuilder buffer = new StringBuilder(); 567 toString(buffer); 568 return buffer.toString(); 569 } 570 571 572 573 /** 574 * Appends a string representation of this protocol element to the provided 575 * buffer. 576 * 577 * @param buffer The buffer into which the string representation should be 578 * written. 579 */ 580 public void toString(StringBuilder buffer) 581 { 582 buffer.append("LDAPMessage(msgID="); 583 buffer.append(messageID); 584 buffer.append(", protocolOp="); 585 if (protocolOp != null) { 586 protocolOp.toString(buffer); 587 } else { 588 buffer.append("null"); 589 } 590 591 if (controls != null && !controls.isEmpty()) 592 { 593 buffer.append(", controls={ "); 594 595 Iterator<Control> iterator = controls.iterator(); 596 iterator.next().toString(buffer); 597 598 while (iterator.hasNext()) 599 { 600 buffer.append(", "); 601 iterator.next().toString(buffer); 602 } 603 604 buffer.append(" }"); 605 } 606 607 buffer.append(")"); 608 } 609 610 611 612 /** 613 * Appends a string representation of this protocol element to the provided 614 * buffer. 615 * 616 * @param buffer The buffer into which the string representation should be 617 * written. 618 * @param indent The number of spaces that should be used to indent the 619 * resulting string representation. 620 */ 621 public void toString(StringBuilder buffer, int indent) 622 { 623 StringBuilder indentBuf = new StringBuilder(indent); 624 for (int i=0 ; i < indent; i++) 625 { 626 indentBuf.append(' '); 627 } 628 629 buffer.append(indentBuf); 630 buffer.append("LDAP LocalizableMessage"); 631 buffer.append(EOL); 632 633 buffer.append(indentBuf); 634 buffer.append(" LocalizableMessage ID: "); 635 buffer.append(messageID); 636 buffer.append(EOL); 637 638 buffer.append(indentBuf); 639 buffer.append(" Protocol Op:"); 640 buffer.append(EOL); 641 protocolOp.toString(buffer, indent+4); 642 643 if (controls != null && !controls.isEmpty()) 644 { 645 buffer.append(indentBuf); 646 buffer.append(" Controls:"); 647 648 for (Control c : controls) 649 { 650 // TODO: Indent 651 c.toString(buffer);//, indent+4); 652 } 653 } 654 } 655} 656