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