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 2009-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2011-2016 ForgeRock AS. 016 */ 017 018package org.forgerock.opendj.ldap; 019 020import java.io.Closeable; 021import java.util.Collection; 022 023import org.forgerock.i18n.LocalizedIllegalArgumentException; 024import org.forgerock.opendj.ldap.requests.AbandonRequest; 025import org.forgerock.opendj.ldap.requests.AddRequest; 026import org.forgerock.opendj.ldap.requests.BindRequest; 027import org.forgerock.opendj.ldap.requests.CompareRequest; 028import org.forgerock.opendj.ldap.requests.DeleteRequest; 029import org.forgerock.opendj.ldap.requests.ExtendedRequest; 030import org.forgerock.opendj.ldap.requests.ModifyDNRequest; 031import org.forgerock.opendj.ldap.requests.ModifyRequest; 032import org.forgerock.opendj.ldap.requests.SearchRequest; 033import org.forgerock.opendj.ldap.requests.UnbindRequest; 034import org.forgerock.opendj.ldap.responses.BindResult; 035import org.forgerock.opendj.ldap.responses.CompareResult; 036import org.forgerock.opendj.ldap.responses.ExtendedResult; 037import org.forgerock.opendj.ldap.responses.GenericExtendedResult; 038import org.forgerock.opendj.ldap.responses.Result; 039import org.forgerock.opendj.ldap.responses.SearchResultEntry; 040import org.forgerock.opendj.ldap.responses.SearchResultReference; 041import org.forgerock.opendj.ldif.ChangeRecord; 042import org.forgerock.opendj.ldif.ConnectionEntryReader; 043 044/** 045 * A connection with a Directory Server over which read and update operations 046 * may be performed. See RFC 4511 for the LDAPv3 protocol specification and more 047 * information about the types of operations defined in LDAP. 048 * <p> 049 * <h3>Operation processing</h3> 050 * <p> 051 * Operations may be performed synchronously or asynchronously depending on the 052 * method chosen. Asynchronous methods can be identified by their {@code Async} 053 * suffix. 054 * <p> 055 * <h4>Performing operations synchronously</h4> 056 * <p> 057 * Synchronous methods block until a response is received from the Directory 058 * Server, at which point an appropriate {@link Result} object is returned if 059 * the operation succeeded, or thrown as an {@link LdapException} if the 060 * operation failed. 061 * <p> 062 * Since synchronous operations block the calling thread, the only way to 063 * abandon a long running operation is to interrupt the calling thread from 064 * another thread. This will cause the calling thread unblock and throw a 065 * {@link CancelledResultException} whose cause is the underlying 066 * {@link InterruptedException}. 067 * <p> 068 * <h4>Performing operations asynchronously</h4> 069 * <p> 070 * Asynchronous methods, identified by their {@code Async} suffix, are 071 * non-blocking, returning a {@link LdapPromise} or sub-type thereof which can 072 * be used for retrieving the result using the {@link LdapPromise#get} method. 073 * Operation failures, for whatever reason, are signaled by the 074 * {@link LdapPromise#get()} method throwing an {@link LdapException}. 075 * <p> 076 * In addition to returning a {@link LdapPromise}, all asynchronous methods 077 * accept a {@link LdapResultHandler} which will be notified upon completion of the 078 * operation. 079 * <p> 080 * Synchronous operations are easily simulated by immediately getting the 081 * result: 082 * 083 * <pre> 084 * Connection connection = ...; 085 * AddRequest request = ...; 086 * // Will block until operation completes, and 087 * // throws exception on failure. 088 * connection.add(request).get(); 089 * </pre> 090 * 091 * Operations can be performed in parallel while taking advantage of the 092 * simplicity of a synchronous application design: 093 * 094 * <pre> 095 * Connection connection1 = ...; 096 * Connection connection2 = ...; 097 * AddRequest request = ...; 098 * // Add the entry to the first server (don't block). 099 * LdapPromise promise1 = connection1.add(request); 100 * // Add the entry to the second server (in parallel). 101 * LdapPromise promise2 = connection2.add(request); 102 * // Total time = is O(1) instead of O(n). 103 * promise1.get(); 104 * promise2.get(); 105 * </pre> 106 * 107 * More complex client applications can take advantage of a fully asynchronous 108 * event driven design using {@link LdapResultHandler}s: 109 * 110 * <pre> 111 * Connection connection = ...; 112 * SearchRequest request = ...; 113 * // Process results in the search result handler 114 * // in a separate thread. 115 * SearchResponseHandler handle = ...; 116 * connection.search(request, handler); 117 * </pre> 118 * <p> 119 * <h3>Closing connections</h3> 120 * <p> 121 * Applications must ensure that a connection is closed by calling 122 * {@link #close()} even if a fatal error occurs on the connection. Once a 123 * connection has been closed by the client application, any attempts to 124 * continue to use the connection will result in an 125 * {@link IllegalStateException} being thrown. Note that, if a fatal error is 126 * encountered on the connection, then the application can continue to use the 127 * connection. In this case all requests subsequent to the failure will fail 128 * with an appropriate {@link LdapException} when their result is 129 * retrieved. 130 * <p> 131 * <h3>Event notification</h3> 132 * <p> 133 * Applications can choose to be notified when a connection is closed by the 134 * application, receives an unsolicited notification, or experiences a fatal 135 * error by registering a {@link ConnectionEventListener} with the connection 136 * using the {@link #addConnectionEventListener} method. 137 * 138 * @see <a href="http://tools.ietf.org/html/rfc4511">RFC 4511 - Lightweight 139 * Directory Access Protocol (LDAP): The Protocol </a> 140 */ 141public interface Connection extends Closeable { 142 143 /** 144 * Abandons the unfinished operation identified in the provided abandon 145 * request. 146 * <p> 147 * Abandon requests do not have a response, so invoking the method get() on 148 * the returned promise will not block, nor return anything (it is Void), but 149 * may throw an exception if a problem occurred while sending the abandon 150 * request. In addition the returned promise may be used in order to 151 * determine the message ID of the abandon request. 152 * <p> 153 * <b>Note:</b> a more convenient approach to abandoning unfinished 154 * asynchronous operations is provided via the 155 * {@link LdapPromise#cancel(boolean)} method. 156 * 157 * @param request 158 * The request identifying the operation to be abandoned. 159 * @return A promise whose result is Void. 160 * @throws UnsupportedOperationException 161 * If this connection does not support abandon operations. 162 * @throws IllegalStateException 163 * If this connection has already been closed, i.e. if 164 * {@code isClosed() == true}. 165 * @throws NullPointerException 166 * If {@code request} was {@code null}. 167 */ 168 LdapPromise<Void> abandonAsync(AbandonRequest request); 169 170 /** 171 * Adds an entry to the Directory Server using the provided add request. 172 * 173 * @param request 174 * The add request. 175 * @return The result of the operation. 176 * @throws LdapException 177 * If the result code indicates that the request failed for some 178 * reason. 179 * @throws UnsupportedOperationException 180 * If this connection does not support add operations. 181 * @throws IllegalStateException 182 * If this connection has already been closed, i.e. if 183 * {@code isClosed() == true}. 184 * @throws NullPointerException 185 * If {@code request} was {@code null}. 186 */ 187 Result add(AddRequest request) throws LdapException; 188 189 /** 190 * Adds the provided entry to the Directory Server. 191 * <p> 192 * This method is equivalent to the following code: 193 * 194 * <pre> 195 * AddRequest request = new AddRequest(entry); 196 * connection.add(request); 197 * </pre> 198 * 199 * @param entry 200 * The entry to be added. 201 * @return The result of the operation. 202 * @throws LdapException 203 * If the result code indicates that the request failed for some 204 * reason. 205 * @throws UnsupportedOperationException 206 * If this connection does not support add operations. 207 * @throws IllegalStateException 208 * If this connection has already been closed, i.e. if 209 * {@code isClosed() == true}. 210 * @throws NullPointerException 211 * If {@code entry} was {@code null} . 212 */ 213 Result add(Entry entry) throws LdapException; 214 215 /** 216 * Adds an entry to the Directory Server using the provided lines of LDIF. 217 * <p> 218 * This method is equivalent to the following code: 219 * 220 * <pre> 221 * AddRequest request = new AddRequest(ldifLines); 222 * connection.add(request); 223 * </pre> 224 * 225 * @param ldifLines 226 * Lines of LDIF containing the an LDIF add change record or an 227 * LDIF entry record. 228 * @return The result of the operation. 229 * @throws LdapException 230 * If the result code indicates that the request failed for some 231 * reason. 232 * @throws UnsupportedOperationException 233 * If this connection does not support add operations. 234 * @throws LocalizedIllegalArgumentException 235 * If {@code ldifLines} was empty, or contained invalid LDIF, or 236 * could not be decoded using the default schema. 237 * @throws IllegalStateException 238 * If this connection has already been closed, i.e. if 239 * {@code isClosed() == true}. 240 * @throws NullPointerException 241 * If {@code ldifLines} was {@code null} . 242 */ 243 Result add(String... ldifLines) throws LdapException; 244 245 /** 246 * Asynchronously adds an entry to the Directory Server using the provided 247 * add request. 248 * 249 * @param request 250 * The add request. 251 * @return A promise representing the result of the operation. 252 * @throws UnsupportedOperationException 253 * If this connection does not support add operations. 254 * @throws IllegalStateException 255 * If this connection has already been closed, i.e. if 256 * {@code isClosed() == true}. 257 * @throws NullPointerException 258 * If {@code request} was {@code null}. 259 */ 260 LdapPromise<Result> addAsync(AddRequest request); 261 262 /** 263 * Asynchronously adds an entry to the Directory Server using the provided 264 * add request. 265 * 266 * @param request 267 * The add request. 268 * @param intermediateResponseHandler 269 * An intermediate response handler which can be used to process 270 * any intermediate responses as they are received, may be 271 * {@code null}. 272 * @return A promise representing the result of the operation. 273 * @throws UnsupportedOperationException 274 * If this connection does not support add operations. 275 * @throws IllegalStateException 276 * If this connection has already been closed, i.e. if 277 * {@code isClosed() == true}. 278 * @throws NullPointerException 279 * If {@code request} was {@code null}. 280 */ 281 LdapPromise<Result> addAsync(AddRequest request, IntermediateResponseHandler intermediateResponseHandler); 282 283 /** 284 * Registers the provided connection event listener so that it will be 285 * notified when this connection is closed by the application, receives an 286 * unsolicited notification, or experiences a fatal error. 287 * 288 * @param listener 289 * The listener which wants to be notified when events occur on 290 * this connection. 291 * @throws IllegalStateException 292 * If this connection has already been closed, i.e. if 293 * {@code isClosed() == true}. 294 * @throws NullPointerException 295 * If the {@code listener} was {@code null}. 296 */ 297 void addConnectionEventListener(ConnectionEventListener listener); 298 299 /** 300 * Applies the provided change request to the Directory Server. 301 * 302 * @param request 303 * The change request. 304 * @return The result of the operation. 305 * @throws LdapException 306 * If the result code indicates that the request failed for some 307 * reason. 308 * @throws UnsupportedOperationException 309 * If this connection does not support the provided change 310 * request. 311 * @throws IllegalStateException 312 * If this connection has already been closed, i.e. if 313 * {@code isClosed() == true}. 314 * @throws NullPointerException 315 * If {@code request} was {@code null}. 316 */ 317 Result applyChange(ChangeRecord request) throws LdapException; 318 319 /** 320 * Asynchronously applies the provided change request to the Directory 321 * Server. 322 * 323 * @param request 324 * The change request. 325 * @return A promise representing the result of the operation. 326 * @throws UnsupportedOperationException 327 * If this connection does not support the provided change 328 * request. 329 * @throws IllegalStateException 330 * If this connection has already been closed, i.e. if 331 * {@code isClosed() == true}. 332 * @throws NullPointerException 333 * If {@code request} was {@code null}. 334 */ 335 LdapPromise<Result> applyChangeAsync(ChangeRecord request); 336 337 /** 338 * Asynchronously applies the provided change request to the Directory 339 * Server. 340 * 341 * @param request 342 * The change request. 343 * @param intermediateResponseHandler 344 * An intermediate response handler which can be used to process 345 * any intermediate responses as they are received, may be 346 * {@code null}. 347 * @return A promise representing the result of the operation. 348 * @throws UnsupportedOperationException 349 * If this connection does not support the provided change 350 * request. 351 * @throws IllegalStateException 352 * If this connection has already been closed, i.e. if 353 * {@code isClosed() == true}. 354 * @throws NullPointerException 355 * If {@code request} was {@code null}. 356 */ 357 LdapPromise<Result> applyChangeAsync(ChangeRecord request, 358 IntermediateResponseHandler intermediateResponseHandler); 359 360 /** 361 * Authenticates to the Directory Server using the provided bind request. 362 * 363 * @param request 364 * The bind request. 365 * @return The result of the operation. 366 * @throws LdapException 367 * If the result code indicates that the request failed for some 368 * reason. 369 * @throws UnsupportedOperationException 370 * If this connection does not support bind operations. 371 * @throws IllegalStateException 372 * If this connection has already been closed, i.e. if 373 * {@code isClosed() == true}. 374 * @throws NullPointerException 375 * If {@code request} was {@code null}. 376 */ 377 BindResult bind(BindRequest request) throws LdapException; 378 379 /** 380 * Authenticates to the Directory Server using simple authentication and the 381 * provided user name and password. 382 * <p> 383 * This method is equivalent to the following code: 384 * 385 * <pre> 386 * BindRequest request = new SimpleBindRequest(name, password); 387 * connection.bind(request); 388 * </pre> 389 * 390 * @param name 391 * The distinguished name of the Directory object that the client 392 * wishes to bind as, which may be empty. 393 * @param password 394 * The password of the Directory object that the client wishes to 395 * bind as, which may be empty. 396 * @return The result of the operation. 397 * @throws LdapException 398 * If the result code indicates that the request failed for some 399 * reason. 400 * @throws LocalizedIllegalArgumentException 401 * If {@code name} could not be decoded using the default 402 * schema. 403 * @throws UnsupportedOperationException 404 * If this connection does not support bind operations. 405 * @throws IllegalStateException 406 * If this connection has already been closed, i.e. if 407 * {@code isClosed() == true}. 408 * @throws NullPointerException 409 * If {@code name} or {@code password} was {@code null}. 410 */ 411 BindResult bind(String name, char[] password) throws LdapException; 412 413 /** 414 * Asynchronously authenticates to the Directory Server using the provided 415 * bind request. 416 * 417 * @param request 418 * The bind request. 419 * @return A promise representing the result of the operation. 420 * @throws UnsupportedOperationException 421 * If this connection does not support bind operations. 422 * @throws IllegalStateException 423 * If this connection has already been closed, i.e. if 424 * {@code isClosed() == true}. 425 * @throws NullPointerException 426 * If {@code request} was {@code null}. 427 */ 428 LdapPromise<BindResult> bindAsync(BindRequest request); 429 430 /** 431 * Asynchronously authenticates to the Directory Server using the provided 432 * bind request. 433 * 434 * @param request 435 * The bind request. 436 * @param intermediateResponseHandler 437 * An intermediate response handler which can be used to process 438 * any intermediate responses as they are received, may be 439 * {@code null}. 440 * @return A promise representing the result of the operation. 441 * @throws UnsupportedOperationException 442 * If this connection does not support bind operations. 443 * @throws IllegalStateException 444 * If this connection has already been closed, i.e. if 445 * {@code isClosed() == true}. 446 * @throws NullPointerException 447 * If {@code request} was {@code null}. 448 */ 449 LdapPromise<BindResult> bindAsync(BindRequest request, IntermediateResponseHandler intermediateResponseHandler); 450 451 /** 452 * Releases any resources associated with this connection. For physical 453 * connections to a Directory Server this will mean that an unbind request 454 * is sent and the underlying socket is closed. 455 * <p> 456 * Other connection implementations may behave differently, and may choose 457 * not to send an unbind request if its use is inappropriate (for example a 458 * pooled connection will be released and returned to its connection pool 459 * without ever issuing an unbind request). 460 * <p> 461 * This method is equivalent to the following code: 462 * 463 * <pre> 464 * UnbindRequest request = new UnbindRequest(); 465 * connection.close(request); 466 * </pre> 467 * 468 * Calling {@code close} on a connection that is already closed has no 469 * effect. 470 * 471 * @see Connections#uncloseable(Connection) 472 */ 473 @Override 474 void close(); 475 476 /** 477 * Releases any resources associated with this connection. For physical 478 * connections to a Directory Server this will mean that the provided unbind 479 * request is sent and the underlying socket is closed. 480 * <p> 481 * Other connection implementations may behave differently, and may choose 482 * to ignore the provided unbind request if its use is inappropriate (for 483 * example a pooled connection will be released and returned to its 484 * connection pool without ever issuing an unbind request). 485 * <p> 486 * Calling {@code close} on a connection that is already closed has no 487 * effect. 488 * 489 * @param request 490 * The unbind request to use in the case where a physical 491 * connection is closed. 492 * @param reason 493 * A reason describing why the connection was closed. 494 * @throws NullPointerException 495 * If {@code request} was {@code null}. 496 */ 497 void close(UnbindRequest request, String reason); 498 499 /** 500 * Compares an entry in the Directory Server using the provided compare 501 * request. 502 * 503 * @param request 504 * The compare request. 505 * @return The result of the operation. 506 * @throws LdapException 507 * If the result code indicates that the request failed for some 508 * reason. 509 * @throws UnsupportedOperationException 510 * If this connection does not support compare operations. 511 * @throws IllegalStateException 512 * If this connection has already been closed, i.e. if 513 * {@code isClosed() == true}. 514 * @throws NullPointerException 515 * If {@code request} was {@code null}. 516 */ 517 CompareResult compare(CompareRequest request) throws LdapException; 518 519 /** 520 * Compares the named entry in the Directory Server against the provided 521 * attribute value assertion. 522 * <p> 523 * This method is equivalent to the following code: 524 * 525 * <pre> 526 * CompareRequest request = new CompareRequest(name, attributeDescription, assertionValue); 527 * connection.compare(request); 528 * </pre> 529 * 530 * @param name 531 * The distinguished name of the entry to be compared. 532 * @param attributeDescription 533 * The name of the attribute to be compared. 534 * @param assertionValue 535 * The assertion value to be compared. 536 * @return The result of the operation. 537 * @throws LdapException 538 * If the result code indicates that the request failed for some 539 * reason. 540 * @throws LocalizedIllegalArgumentException 541 * If {@code name} or {@code AttributeDescription} could not be 542 * decoded using the default schema. 543 * @throws UnsupportedOperationException 544 * If this connection does not support compare operations. 545 * @throws IllegalStateException 546 * If this connection has already been closed, i.e. if 547 * {@code isClosed() == true}. 548 * @throws NullPointerException 549 * If {@code name}, {@code attributeDescription}, or 550 * {@code assertionValue} was {@code null}. 551 */ 552 CompareResult compare(String name, String attributeDescription, String assertionValue) 553 throws LdapException; 554 555 /** 556 * Asynchronously compares an entry in the Directory Server using the 557 * provided compare request. 558 * 559 * @param request 560 * The compare request. 561 * @return A promise representing the result of the operation. 562 * @throws UnsupportedOperationException 563 * If this connection does not support compare operations. 564 * @throws IllegalStateException 565 * If this connection has already been closed, i.e. if 566 * {@code isClosed() == true}. 567 * @throws NullPointerException 568 * If {@code request} was {@code null}. 569 */ 570 LdapPromise<CompareResult> compareAsync(CompareRequest request); 571 572 /** 573 * Asynchronously compares an entry in the Directory Server using the 574 * provided compare request. 575 * 576 * @param request 577 * The compare request. 578 * @param intermediateResponseHandler 579 * An intermediate response handler which can be used to process 580 * any intermediate responses as they are received, may be 581 * {@code null}. 582 * @return A promise representing the result of the operation. 583 * @throws UnsupportedOperationException 584 * If this connection does not support compare operations. 585 * @throws IllegalStateException 586 * If this connection has already been closed, i.e. if 587 * {@code isClosed() == true}. 588 * @throws NullPointerException 589 * If {@code request} was {@code null}. 590 */ 591 LdapPromise<CompareResult> compareAsync(CompareRequest request, 592 IntermediateResponseHandler intermediateResponseHandler); 593 594 /** 595 * Deletes an entry from the Directory Server using the provided delete 596 * request. 597 * 598 * @param request 599 * The delete request. 600 * @return The result of the operation. 601 * @throws LdapException 602 * If the result code indicates that the request failed for some 603 * reason. 604 * @throws UnsupportedOperationException 605 * If this connection does not support delete operations. 606 * @throws IllegalStateException 607 * If this connection has already been closed, i.e. if 608 * {@code isClosed() == true}. 609 * @throws NullPointerException 610 * If {@code request} was {@code null}. 611 */ 612 Result delete(DeleteRequest request) throws LdapException; 613 614 /** 615 * Deletes the named entry from the Directory Server. 616 * <p> 617 * This method is equivalent to the following code: 618 * 619 * <pre> 620 * DeleteRequest request = new DeleteRequest(name); 621 * connection.delete(request); 622 * </pre> 623 * 624 * @param name 625 * The distinguished name of the entry to be deleted. 626 * @return The result of the operation. 627 * @throws LdapException 628 * If the result code indicates that the request failed for some 629 * reason. 630 * @throws LocalizedIllegalArgumentException 631 * If {@code name} could not be decoded using the default 632 * schema. 633 * @throws UnsupportedOperationException 634 * If this connection does not support delete operations. 635 * @throws IllegalStateException 636 * If this connection has already been closed, i.e. if 637 * {@code isClosed() == true}. 638 * @throws NullPointerException 639 * If {@code name} was {@code null}. 640 */ 641 Result delete(String name) throws LdapException; 642 643 /** 644 * Deletes the named entry and all of its subordinates from the Directory 645 * Server. 646 * <p> 647 * This method is equivalent to the following code: 648 * 649 * <pre> 650 * DeleteRequest request = new DeleteRequest(name).addControl( 651 * connection.delete(request); 652 * </pre> 653 * 654 * @param name 655 * The distinguished name of the subtree base entry to be 656 * deleted. 657 * @return The result of the operation. 658 * @throws LdapException 659 * If the result code indicates that the request failed for some 660 * reason. 661 * @throws LocalizedIllegalArgumentException 662 * If {@code name} could not be decoded using the default 663 * schema. 664 * @throws UnsupportedOperationException 665 * If this connection does not support delete operations. 666 * @throws IllegalStateException 667 * If this connection has already been closed, i.e. if 668 * {@code isClosed() == true}. 669 * @throws NullPointerException 670 * If {@code name} was {@code null}. 671 */ 672 Result deleteSubtree(String name) throws LdapException; 673 674 /** 675 * Asynchronously deletes an entry from the Directory Server using the 676 * provided delete request. 677 * 678 * @param request 679 * The delete request. 680 * @return A promise representing the result of the operation. 681 * @throws UnsupportedOperationException 682 * If this connection does not support delete operations. 683 * @throws IllegalStateException 684 * If this connection has already been closed, i.e. if 685 * {@code isClosed() == true}. 686 * @throws NullPointerException 687 * If {@code request} was {@code null}. 688 */ 689 LdapPromise<Result> deleteAsync(DeleteRequest request); 690 691 /** 692 * Asynchronously deletes an entry from the Directory Server using the 693 * provided delete request. 694 * 695 * @param request 696 * The delete request. 697 * @param intermediateResponseHandler 698 * An intermediate response handler which can be used to process 699 * any intermediate responses as they are received, may be 700 * {@code null}. 701 * @return A promise representing the result of the operation. 702 * @throws UnsupportedOperationException 703 * If this connection does not support delete operations. 704 * @throws IllegalStateException 705 * If this connection has already been closed, i.e. if 706 * {@code isClosed() == true}. 707 * @throws NullPointerException 708 * If {@code request} was {@code null}. 709 */ 710 LdapPromise<Result> deleteAsync(DeleteRequest request, IntermediateResponseHandler intermediateResponseHandler); 711 712 /** 713 * Requests that the Directory Server performs the provided extended 714 * request. 715 * 716 * @param <R> 717 * The type of result returned by the extended request. 718 * @param request 719 * The extended request. 720 * @return The result of the operation. 721 * @throws LdapException 722 * If the result code indicates that the request failed for some 723 * reason. 724 * @throws UnsupportedOperationException 725 * If this connection does not support extended operations. 726 * @throws IllegalStateException 727 * If this connection has already been closed, i.e. if 728 * {@code isClosed() == true}. 729 * @throws NullPointerException 730 * If {@code request} was {@code null}. 731 */ 732 <R extends ExtendedResult> R extendedRequest(ExtendedRequest<R> request) throws LdapException; 733 734 /** 735 * Requests that the Directory Server performs the provided extended 736 * request, optionally listening for any intermediate responses. 737 * 738 * @param <R> 739 * The type of result returned by the extended request. 740 * @param request 741 * The extended request. 742 * @param handler 743 * An intermediate response handler which can be used to process 744 * any intermediate responses as they are received, may be 745 * {@code null}. 746 * @return The result of the operation. 747 * @throws LdapException 748 * If the result code indicates that the request failed for some 749 * reason. 750 * @throws UnsupportedOperationException 751 * If this connection does not support extended operations. 752 * @throws IllegalStateException 753 * If this connection has already been closed, i.e. if 754 * {@code isClosed() == true}. 755 * @throws NullPointerException 756 * If {@code request} was {@code null}. 757 */ 758 <R extends ExtendedResult> R extendedRequest(ExtendedRequest<R> request, IntermediateResponseHandler handler) 759 throws LdapException; 760 761 /** 762 * Requests that the Directory Server performs the provided extended 763 * request. 764 * <p> 765 * This method is equivalent to the following code: 766 * 767 * <pre> 768 * GenericExtendedRequest request = new GenericExtendedRequest(requestName, requestValue); 769 * connection.extendedRequest(request); 770 * </pre> 771 * 772 * @param requestName 773 * The dotted-decimal representation of the unique OID 774 * corresponding to the extended request. 775 * @param requestValue 776 * The content of the extended request in a form defined by the 777 * extended operation, or {@code null} if there is no content. 778 * @return The result of the operation. 779 * @throws LdapException 780 * If the result code indicates that the request failed for some 781 * reason. 782 * @throws UnsupportedOperationException 783 * If this connection does not support extended operations. 784 * @throws IllegalStateException 785 * If this connection has already been closed, i.e. if 786 * {@code isClosed() == true}. 787 * @throws NullPointerException 788 * If {@code requestName} was {@code null}. 789 */ 790 GenericExtendedResult extendedRequest(String requestName, ByteString requestValue) throws LdapException; 791 792 /** 793 * Asynchronously performs the provided extended request in the Directory 794 * Server. 795 * 796 * @param <R> 797 * The type of result returned by the extended request. 798 * @param request 799 * The extended request. 800 * @return A promise representing the result of the operation. 801 * @throws UnsupportedOperationException 802 * If this connection does not support extended operations. 803 * @throws IllegalStateException 804 * If this connection has already been closed, i.e. if 805 * {@code isClosed() == true}. 806 * @throws NullPointerException 807 * If {@code request} was {@code null}. 808 */ 809 <R extends ExtendedResult> LdapPromise<R> extendedRequestAsync(ExtendedRequest<R> request); 810 811 /** 812 * Asynchronously performs the provided extended request in the Directory 813 * Server. 814 * 815 * @param <R> 816 * The type of result returned by the extended request. 817 * @param request 818 * The extended request. 819 * @param intermediateResponseHandler 820 * An intermediate response handler which can be used to process 821 * any intermediate responses as they are received, may be 822 * {@code null}. 823 * @return A promise representing the result of the operation. 824 * @throws UnsupportedOperationException 825 * If this connection does not support extended operations. 826 * @throws IllegalStateException 827 * If this connection has already been closed, i.e. if 828 * {@code isClosed() == true}. 829 * @throws NullPointerException 830 * If {@code request} was {@code null}. 831 */ 832 <R extends ExtendedResult> LdapPromise<R> extendedRequestAsync(ExtendedRequest<R> request, 833 IntermediateResponseHandler intermediateResponseHandler); 834 835 /** 836 * Indicates whether this connection has been explicitly closed by 837 * calling {@code close}. This method will not return {@code true} if a 838 * fatal error has occurred on the connection unless {@code close} has been 839 * called. 840 * 841 * @return {@code true} if this connection has been explicitly closed by 842 * calling {@code close}, or {@code false} otherwise. 843 */ 844 boolean isClosed(); 845 846 /** 847 * Returns {@code true} if this connection has not been closed and no fatal 848 * errors have been detected. This method is guaranteed to return 849 * {@code false} only when it is called after the method {@code close} has 850 * been called. 851 * 852 * @return {@code true} if this connection is valid, {@code false} 853 * otherwise. 854 */ 855 boolean isValid(); 856 857 /** 858 * Modifies an entry in the Directory Server using the provided modify 859 * request. 860 * 861 * @param request 862 * The modify request. 863 * @return The result of the operation. 864 * @throws LdapException 865 * If the result code indicates that the request failed for some 866 * reason. 867 * @throws UnsupportedOperationException 868 * If this connection does not support modify operations. 869 * @throws IllegalStateException 870 * If this connection has already been closed, i.e. if 871 * {@code isClosed() == true}. 872 * @throws NullPointerException 873 * If {@code request} was {@code null}. 874 */ 875 Result modify(ModifyRequest request) throws LdapException; 876 877 /** 878 * Modifies an entry in the Directory Server using the provided lines of 879 * LDIF. 880 * <p> 881 * This method is equivalent to the following code: 882 * 883 * <pre> 884 * ModifyRequest request = new ModifyRequest(name, ldifChanges); 885 * connection.modify(request); 886 * </pre> 887 * 888 * @param ldifLines 889 * Lines of LDIF containing the a single LDIF modify change 890 * record. 891 * @return The result of the operation. 892 * @throws LdapException 893 * If the result code indicates that the request failed for some 894 * reason. 895 * @throws UnsupportedOperationException 896 * If this connection does not support modify operations. 897 * @throws LocalizedIllegalArgumentException 898 * If {@code ldifLines} was empty, or contained invalid LDIF, or 899 * could not be decoded using the default schema. 900 * @throws IllegalStateException 901 * If this connection has already been closed, i.e. if 902 * {@code isClosed() == true}. 903 * @throws NullPointerException 904 * If {@code ldifLines} was {@code null} . 905 */ 906 Result modify(String... ldifLines) throws LdapException; 907 908 /** 909 * Asynchronously modifies an entry in the Directory Server using the 910 * provided modify request. 911 * 912 * @param request 913 * The modify request. 914 * @return A promise representing the result of the operation. 915 * @throws UnsupportedOperationException 916 * If this connection does not support modify operations. 917 * @throws IllegalStateException 918 * If this connection has already been closed, i.e. if 919 * {@code isClosed() == true}. 920 * @throws NullPointerException 921 * If {@code request} was {@code null}. 922 */ 923 LdapPromise<Result> modifyAsync(ModifyRequest request); 924 925 /** 926 * Asynchronously modifies an entry in the Directory Server using the 927 * provided modify request. 928 * 929 * @param request 930 * The modify request. 931 * @param intermediateResponseHandler 932 * An intermediate response handler which can be used to process 933 * any intermediate responses as they are received, may be 934 * {@code null}. 935 * @return A promise representing the result of the operation. 936 * @throws UnsupportedOperationException 937 * If this connection does not support modify operations. 938 * @throws IllegalStateException 939 * If this connection has already been closed, i.e. if 940 * {@code isClosed() == true}. 941 * @throws NullPointerException 942 * If {@code request} was {@code null}. 943 */ 944 LdapPromise<Result> modifyAsync(ModifyRequest request, IntermediateResponseHandler intermediateResponseHandler); 945 946 /** 947 * Renames an entry in the Directory Server using the provided modify DN 948 * request. 949 * 950 * @param request 951 * The modify DN request. 952 * @return The result of the operation. 953 * @throws LdapException 954 * If the result code indicates that the request failed for some 955 * reason. 956 * @throws UnsupportedOperationException 957 * If this connection does not support modify DN operations. 958 * @throws IllegalStateException 959 * If this connection has already been closed, i.e. if 960 * {@code isClosed() == true}. 961 * @throws NullPointerException 962 * If {@code request} was {@code null}. 963 */ 964 Result modifyDN(ModifyDNRequest request) throws LdapException; 965 966 /** 967 * Renames the named entry in the Directory Server using the provided new 968 * RDN. 969 * <p> 970 * This method is equivalent to the following code: 971 * 972 * <pre> 973 * ModifyDNRequest request = new ModifyDNRequest(name, newRDN); 974 * connection.modifyDN(request); 975 * </pre> 976 * 977 * @param name 978 * The distinguished name of the entry to be renamed. 979 * @param newRDN 980 * The new RDN of the entry. 981 * @return The result of the operation. 982 * @throws LdapException 983 * If the result code indicates that the request failed for some 984 * reason. 985 * @throws LocalizedIllegalArgumentException 986 * If {@code name} or {@code newRDN} could not be decoded using 987 * the default schema. 988 * @throws UnsupportedOperationException 989 * If this connection does not support modify DN operations. 990 * @throws IllegalStateException 991 * If this connection has already been closed, i.e. if 992 * {@code isClosed() == true}. 993 * @throws NullPointerException 994 * If {@code name} or {@code newRDN} was {@code null}. 995 */ 996 Result modifyDN(String name, String newRDN) throws LdapException; 997 998 /** 999 * Asynchronously renames an entry in the Directory Server using the 1000 * provided modify DN request. 1001 * 1002 * @param request 1003 * The modify DN request. 1004 * @return A promise representing the result of the operation. 1005 * @throws UnsupportedOperationException 1006 * If this connection does not support modify DN operations. 1007 * @throws IllegalStateException 1008 * If this connection has already been closed, i.e. if 1009 * {@code isClosed() == true}. 1010 * @throws NullPointerException 1011 * If {@code request} was {@code null}. 1012 */ 1013 LdapPromise<Result> modifyDNAsync(ModifyDNRequest request); 1014 1015 /** 1016 * Asynchronously renames an entry in the Directory Server using the 1017 * provided modify DN request. 1018 * 1019 * @param request 1020 * The modify DN request. 1021 * @param intermediateResponseHandler 1022 * An intermediate response handler which can be used to process 1023 * any intermediate responses as they are received, may be 1024 * {@code null}. 1025 * @return A promise representing the result of the operation. 1026 * @throws UnsupportedOperationException 1027 * If this connection does not support modify DN operations. 1028 * @throws IllegalStateException 1029 * If this connection has already been closed, i.e. if 1030 * {@code isClosed() == true}. 1031 * @throws NullPointerException 1032 * If {@code request} was {@code null}. 1033 */ 1034 LdapPromise<Result> modifyDNAsync(ModifyDNRequest request, 1035 IntermediateResponseHandler intermediateResponseHandler); 1036 1037 /** 1038 * Reads the named entry from the Directory Server. 1039 * <p> 1040 * If the requested entry is not returned by the Directory Server then the 1041 * request will fail with an {@link EntryNotFoundException}. More 1042 * specifically, this method will never return {@code null}. 1043 * <p> 1044 * This method is equivalent to the following code: 1045 * 1046 * <pre> 1047 * SearchRequest request = new SearchRequest(name, SearchScope.BASE_OBJECT, 1048 * "(objectClass=*)", attributeDescriptions); 1049 * connection.searchSingleEntry(request); 1050 * </pre> 1051 * 1052 * @param name 1053 * The distinguished name of the entry to be read. 1054 * @param attributeDescriptions 1055 * The names of the attributes to be included with the entry, 1056 * which may be {@code null} or empty indicating that all user 1057 * attributes should be returned. 1058 * @return The single search result entry returned from the search. 1059 * @throws LdapException 1060 * If the result code indicates that the request failed for some 1061 * reason. 1062 * @throws UnsupportedOperationException 1063 * If this connection does not support search operations. 1064 * @throws IllegalStateException 1065 * If this connection has already been closed, i.e. if 1066 * {@code isClosed() == true}. 1067 * @throws NullPointerException 1068 * If the {@code name} was {@code null}. 1069 */ 1070 SearchResultEntry readEntry(DN name, String... attributeDescriptions) throws LdapException; 1071 1072 /** 1073 * Reads the named entry from the Directory Server. 1074 * <p> 1075 * If the requested entry is not returned by the Directory Server then the 1076 * request will fail with an {@link EntryNotFoundException}. More 1077 * specifically, this method will never return {@code null}. 1078 * <p> 1079 * This method is equivalent to the following code: 1080 * 1081 * <pre> 1082 * SearchRequest request = 1083 * new SearchRequest(name, SearchScope.BASE_OBJECT, "(objectClass=*)", attributeDescriptions); 1084 * connection.searchSingleEntry(request); 1085 * </pre> 1086 * 1087 * @param name 1088 * The distinguished name of the entry to be read. 1089 * @param attributeDescriptions 1090 * The names of the attributes to be included with the entry. 1091 * @return The single search result entry returned from the search. 1092 * @throws LdapException 1093 * If the result code indicates that the request failed for some 1094 * reason. 1095 * @throws LocalizedIllegalArgumentException 1096 * If {@code baseObject} could not be decoded using the default 1097 * schema. 1098 * @throws UnsupportedOperationException 1099 * If this connection does not support search operations. 1100 * @throws IllegalStateException 1101 * If this connection has already been closed, i.e. if 1102 * {@code isClosed() == true}. 1103 * @throws NullPointerException 1104 * If the {@code name} was {@code null}. 1105 */ 1106 SearchResultEntry readEntry(String name, String... attributeDescriptions) throws LdapException; 1107 1108 /** 1109 * Asynchronously reads the named entry from the Directory Server. 1110 * <p> 1111 * If the requested entry is not returned by the Directory Server then the 1112 * request will fail with an {@link EntryNotFoundException}. More 1113 * specifically, the returned promise will never return {@code null}. 1114 * <p> 1115 * This method is equivalent to the following code: 1116 * 1117 * <pre> 1118 * SearchRequest request = 1119 * new SearchRequest(name, SearchScope.BASE_OBJECT, "(objectClass=*)", attributeDescriptions); 1120 * connection.searchSingleEntryAsync(request, resultHandler, p); 1121 * </pre> 1122 * 1123 * @param name 1124 * The distinguished name of the entry to be read. 1125 * @param attributeDescriptions 1126 * The names of the attributes to be included with the entry, 1127 * which may be {@code null} or empty indicating that all user 1128 * attributes should be returned. 1129 * @return A promise representing the result of the operation. 1130 * @throws UnsupportedOperationException 1131 * If this connection does not support search operations. 1132 * @throws IllegalStateException 1133 * If this connection has already been closed, i.e. if 1134 * {@code isClosed() == true}. 1135 * @throws NullPointerException 1136 * If the {@code name} was {@code null}. 1137 */ 1138 LdapPromise<SearchResultEntry> readEntryAsync(DN name, Collection<String> attributeDescriptions); 1139 1140 /** 1141 * Removes the provided connection event listener from this connection so 1142 * that it will no longer be notified when this connection is closed by the 1143 * application, receives an unsolicited notification, or experiences a fatal 1144 * error. 1145 * 1146 * @param listener 1147 * The listener which no longer wants to be notified when events 1148 * occur on this connection. 1149 * @throws NullPointerException 1150 * If the {@code listener} was {@code null}. 1151 */ 1152 void removeConnectionEventListener(ConnectionEventListener listener); 1153 1154 /** 1155 * Searches the Directory Server using the provided search parameters. Any 1156 * matching entries returned by the search will be exposed through the 1157 * returned {@code ConnectionEntryReader}. 1158 * <p> 1159 * Unless otherwise specified, calling this method is equivalent to: 1160 * 1161 * <pre> 1162 * ConnectionEntryReader reader = new ConnectionEntryReader(this, request); 1163 * </pre> 1164 * 1165 * @param request 1166 * The search request. 1167 * @return The result of the operation. 1168 * @throws UnsupportedOperationException 1169 * If this connection does not support search operations. 1170 * @throws IllegalStateException 1171 * If this connection has already been closed, i.e. if 1172 * {@code isClosed() == true}. 1173 * @throws NullPointerException 1174 * If {@code request} or {@code entries} was {@code null}. 1175 */ 1176 ConnectionEntryReader search(SearchRequest request); 1177 1178 /** 1179 * Searches the Directory Server using the provided search request. Any 1180 * matching entries returned by the search will be added to {@code entries}, 1181 * even if the final search result indicates that the search failed. Search 1182 * result references will be discarded. 1183 * <p> 1184 * <b>Warning:</b> Usage of this method is discouraged if the search request 1185 * is expected to yield a large number of search results since the entire 1186 * set of results will be stored in memory, potentially causing an 1187 * {@code OutOfMemoryError}. 1188 * <p> 1189 * This method is equivalent to the following code: 1190 * 1191 * <pre> 1192 * connection.search(request, entries, null); 1193 * </pre> 1194 * 1195 * @param request 1196 * The search request. 1197 * @param entries 1198 * The collection to which matching entries should be added. 1199 * @return The result of the operation. 1200 * @throws LdapException 1201 * If the result code indicates that the request failed for some 1202 * reason. 1203 * @throws UnsupportedOperationException 1204 * If this connection does not support search operations. 1205 * @throws IllegalStateException 1206 * If this connection has already been closed, i.e. if 1207 * {@code isClosed() == true}. 1208 * @throws NullPointerException 1209 * If {@code request} or {@code entries} was {@code null}. 1210 */ 1211 Result search(SearchRequest request, Collection<? super SearchResultEntry> entries) throws LdapException; 1212 1213 /** 1214 * Searches the Directory Server using the provided search request. Any 1215 * matching entries returned by the search will be added to {@code entries}, 1216 * even if the final search result indicates that the search failed. 1217 * Similarly, search result references returned by the search will be added 1218 * to {@code references}. 1219 * <p> 1220 * <b>Warning:</b> Usage of this method is discouraged if the search request 1221 * is expected to yield a large number of search results since the entire 1222 * set of results will be stored in memory, potentially causing an 1223 * {@code OutOfMemoryError}. 1224 * 1225 * @param request 1226 * The search request. 1227 * @param entries 1228 * The collection to which matching entries should be added. 1229 * @param references 1230 * The collection to which search result references should be 1231 * added, or {@code null} if references are to be discarded. 1232 * @return The result of the operation. 1233 * @throws LdapException 1234 * If the result code indicates that the request failed for some 1235 * reason. 1236 * @throws UnsupportedOperationException 1237 * If this connection does not support search operations. 1238 * @throws IllegalStateException 1239 * If this connection has already been closed, i.e. if 1240 * {@code isClosed() == true}. 1241 * @throws NullPointerException 1242 * If {@code request} or {@code entries} was {@code null}. 1243 */ 1244 Result search(SearchRequest request, Collection<? super SearchResultEntry> entries, 1245 Collection<? super SearchResultReference> references) throws LdapException; 1246 1247 /** 1248 * Searches the Directory Server using the provided search request. Any 1249 * matching entries returned by the search as well as any search result 1250 * references will be passed to the provided search result handler. 1251 * 1252 * @param request 1253 * The search request. 1254 * @param handler 1255 * A search result handler which can be used to process the 1256 * search result entries and references as they are received, may 1257 * be {@code null}. 1258 * @return The result of the operation. 1259 * @throws LdapException 1260 * If the result code indicates that the request failed for some 1261 * reason. 1262 * @throws UnsupportedOperationException 1263 * If this connection does not support search operations. 1264 * @throws IllegalStateException 1265 * If this connection has already been closed, i.e. if 1266 * {@code isClosed() == true}. 1267 * @throws NullPointerException 1268 * If {@code request} was {@code null}. 1269 */ 1270 Result search(SearchRequest request, SearchResultHandler handler) throws LdapException; 1271 1272 /** 1273 * Searches the Directory Server using the provided search parameters. Any 1274 * matching entries returned by the search will be exposed through the 1275 * {@code EntryReader} interface. 1276 * <p> 1277 * <b>Warning:</b> When using a queue with an optional capacity bound, the 1278 * connection will stop reading responses and wait if necessary for space to 1279 * become available. 1280 * <p> 1281 * This method is equivalent to the following code: 1282 * 1283 * <pre> 1284 * SearchRequest request = new SearchRequest(baseDN, scope, filter, attributeDescriptions); 1285 * connection.search(request, new LinkedBlockingQueue<Response>()); 1286 * </pre> 1287 * 1288 * @param baseObject 1289 * The distinguished name of the base entry relative to which the 1290 * search is to be performed. 1291 * @param scope 1292 * The scope of the search. 1293 * @param filter 1294 * The filter that defines the conditions that must be fulfilled 1295 * in order for an entry to be returned. 1296 * @param attributeDescriptions 1297 * The names of the attributes to be included with each entry. 1298 * @return An entry reader exposing the returned entries. 1299 * @throws UnsupportedOperationException 1300 * If this connection does not support search operations. 1301 * @throws IllegalStateException 1302 * If this connection has already been closed, i.e. if 1303 * {@code isClosed() == true}. 1304 * @throws NullPointerException 1305 * If the {@code baseObject}, {@code scope}, or {@code filter} 1306 * were {@code null}. 1307 */ 1308 ConnectionEntryReader search(String baseObject, SearchScope scope, String filter, 1309 String... attributeDescriptions); 1310 1311 /** 1312 * Asynchronously searches the Directory Server using the provided search 1313 * request. 1314 * 1315 * @param request 1316 * The search request. 1317 * @param entryHandler 1318 * A search result handler which can be used to asynchronously 1319 * process the search result entries and references as they are 1320 * received, may be {@code null}. 1321 * @return A promise representing the result of the operation. 1322 * @throws UnsupportedOperationException 1323 * If this connection does not support search operations. 1324 * @throws IllegalStateException 1325 * If this connection has already been closed, i.e. if 1326 * {@code isClosed() == true}. 1327 * @throws NullPointerException 1328 * If {@code request} was {@code null}. 1329 */ 1330 LdapPromise<Result> searchAsync(SearchRequest request, SearchResultHandler entryHandler); 1331 1332 /** 1333 * Asynchronously searches the Directory Server using the provided search 1334 * request. 1335 * 1336 * @param request 1337 * The search request. 1338 * @param intermediateResponseHandler 1339 * An intermediate response handler which can be used to process 1340 * any intermediate responses as they are received, may be 1341 * {@code null}. 1342 * @param entryHandler 1343 * A search result handler which can be used to asynchronously 1344 * process the search result entries and references as they are 1345 * received, may be {@code null}. 1346 * @return A promise representing the result of the operation. 1347 * @throws UnsupportedOperationException 1348 * If this connection does not support search operations. 1349 * @throws IllegalStateException 1350 * If this connection has already been closed, i.e. if 1351 * {@code isClosed() == true}. 1352 * @throws NullPointerException 1353 * If {@code request} was {@code null}. 1354 */ 1355 LdapPromise<Result> searchAsync(SearchRequest request, IntermediateResponseHandler intermediateResponseHandler, 1356 SearchResultHandler entryHandler); 1357 1358 /** 1359 * Searches the Directory Server for a single entry using the provided 1360 * search request. 1361 * <p> 1362 * If the requested entry is not returned by the Directory Server then the 1363 * request will fail with an {@link EntryNotFoundException}. More 1364 * specifically, this method will never return {@code null}. If multiple 1365 * matching entries are returned by the Directory Server then the request 1366 * will fail with an {@link MultipleEntriesFoundException}. 1367 * 1368 * @param request 1369 * The search request. 1370 * @return The single search result entry returned from the search. 1371 * @throws LdapException 1372 * If the result code indicates that the request failed for some 1373 * reason. 1374 * @throws UnsupportedOperationException 1375 * If this connection does not support search operations. 1376 * @throws IllegalStateException 1377 * If this connection has already been closed, i.e. if 1378 * {@code isClosed() == true}. 1379 * @throws NullPointerException 1380 * If the {@code request} was {@code null}. 1381 */ 1382 SearchResultEntry searchSingleEntry(SearchRequest request) throws LdapException; 1383 1384 /** 1385 * Searches the Directory Server for a single entry using the provided 1386 * search parameters. 1387 * <p> 1388 * If the requested entry is not returned by the Directory Server then the 1389 * request will fail with an {@link EntryNotFoundException}. More 1390 * specifically, this method will never return {@code null}. If multiple 1391 * matching entries are returned by the Directory Server then the request 1392 * will fail with an {@link MultipleEntriesFoundException}. 1393 * <p> 1394 * This method is equivalent to the following code: 1395 * 1396 * <pre> 1397 * SearchRequest request = new SearchRequest(baseObject, scope, filter, attributeDescriptions); 1398 * connection.searchSingleEntry(request); 1399 * </pre> 1400 * 1401 * @param baseObject 1402 * The distinguished name of the base entry relative to which the 1403 * search is to be performed. 1404 * @param scope 1405 * The scope of the search. 1406 * @param filter 1407 * The filter that defines the conditions that must be fulfilled 1408 * in order for an entry to be returned. 1409 * @param attributeDescriptions 1410 * The names of the attributes to be included with each entry. 1411 * @return The single search result entry returned from the search. 1412 * @throws LdapException 1413 * If the result code indicates that the request failed for some 1414 * reason. 1415 * @throws LocalizedIllegalArgumentException 1416 * If {@code baseObject} could not be decoded using the default 1417 * schema or if {@code filter} is not a valid LDAP string 1418 * representation of a filter. 1419 * @throws UnsupportedOperationException 1420 * If this connection does not support search operations. 1421 * @throws IllegalStateException 1422 * If this connection has already been closed, i.e. if 1423 * {@code isClosed() == true}. 1424 * @throws NullPointerException 1425 * If the {@code baseObject}, {@code scope}, or {@code filter} 1426 * were {@code null}. 1427 */ 1428 SearchResultEntry searchSingleEntry(String baseObject, SearchScope scope, String filter, 1429 String... attributeDescriptions) throws LdapException; 1430 1431 /** 1432 * Asynchronously searches the Directory Server for a single entry using the 1433 * provided search request. 1434 * <p> 1435 * If the requested entry is not returned by the Directory Server then the 1436 * request will fail with an {@link EntryNotFoundException}. More 1437 * specifically, the returned promise will never return {@code null}. If 1438 * multiple matching entries are returned by the Directory Server then the 1439 * request will fail with an {@link MultipleEntriesFoundException}. 1440 * 1441 * @param request 1442 * The search request. 1443 * @return A promise representing the result of the operation. 1444 * @throws UnsupportedOperationException 1445 * If this connection does not support search operations. 1446 * @throws IllegalStateException 1447 * If this connection has already been closed, i.e. if 1448 * {@code isClosed() == true}. 1449 * @throws NullPointerException 1450 * If the {@code request} was {@code null}. 1451 */ 1452 LdapPromise<SearchResultEntry> searchSingleEntryAsync(SearchRequest request); 1453}