001/* 002 * Copyright 2009-2017 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2009-2017 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.sdk.migrate.ldapjdk; 022 023 024 025import com.unboundid.asn1.ASN1OctetString; 026import com.unboundid.ldap.sdk.AddRequest; 027import com.unboundid.ldap.sdk.AsyncRequestID; 028import com.unboundid.ldap.sdk.BindResult; 029import com.unboundid.ldap.sdk.CompareRequest; 030import com.unboundid.ldap.sdk.CompareResult; 031import com.unboundid.ldap.sdk.Control; 032import com.unboundid.ldap.sdk.DeleteRequest; 033import com.unboundid.ldap.sdk.DereferencePolicy; 034import com.unboundid.ldap.sdk.ExtendedRequest; 035import com.unboundid.ldap.sdk.ExtendedResult; 036import com.unboundid.ldap.sdk.Filter; 037import com.unboundid.ldap.sdk.InternalSDKHelper; 038import com.unboundid.ldap.sdk.LDAPConnectionOptions; 039import com.unboundid.ldap.sdk.LDAPResult; 040import com.unboundid.ldap.sdk.Modification; 041import com.unboundid.ldap.sdk.ModifyDNRequest; 042import com.unboundid.ldap.sdk.ModifyRequest; 043import com.unboundid.ldap.sdk.ResultCode; 044import com.unboundid.ldap.sdk.SearchRequest; 045import com.unboundid.ldap.sdk.SearchResult; 046import com.unboundid.ldap.sdk.SearchScope; 047import com.unboundid.ldap.sdk.SimpleBindRequest; 048import com.unboundid.ldap.sdk.UpdatableLDAPRequest; 049import com.unboundid.util.Mutable; 050import com.unboundid.util.NotExtensible; 051import com.unboundid.util.ThreadSafety; 052import com.unboundid.util.ThreadSafetyLevel; 053 054import static com.unboundid.util.Debug.*; 055 056 057 058/** 059 * This class provides an object that may be used to communicate with an LDAP 060 * directory server. 061 * <BR><BR> 062 * This class is primarily intended to be used in the process of updating 063 * applications which use the Netscape Directory SDK for Java to switch to or 064 * coexist with the UnboundID LDAP SDK for Java. For applications not written 065 * using the Netscape Directory SDK for Java, the 066 * {@link com.unboundid.ldap.sdk.LDAPConnection} class should be used instead. 067 */ 068@Mutable() 069@NotExtensible() 070@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 071public class LDAPConnection 072{ 073 /** 074 * The integer value for the DEREF_NEVER dereference policy. 075 */ 076 public static final int DEREF_NEVER = DereferencePolicy.NEVER.intValue(); 077 078 079 080 /** 081 * The integer value for the DEREF_SEARCHING dereference policy. 082 */ 083 public static final int DEREF_SEARCHING = 084 DereferencePolicy.SEARCHING.intValue(); 085 086 087 088 /** 089 * The integer value for the DEREF_FINDING dereference policy. 090 */ 091 public static final int DEREF_FINDING = 092 DereferencePolicy.FINDING.intValue(); 093 094 095 096 /** 097 * The integer value for the DEREF_ALWAYS dereference policy. 098 */ 099 public static final int DEREF_ALWAYS = 100 DereferencePolicy.ALWAYS.intValue(); 101 102 103 104 /** 105 * The integer value for the SCOPE_BASE search scope. 106 */ 107 public static final int SCOPE_BASE = SearchScope.BASE_INT_VALUE; 108 109 110 111 /** 112 * The integer value for the SCOPE_ONE search scope. 113 */ 114 public static final int SCOPE_ONE = SearchScope.ONE_INT_VALUE; 115 116 117 118 /** 119 * The integer value for the SCOPE_SUB search scope. 120 */ 121 public static final int SCOPE_SUB = SearchScope.SUB_INT_VALUE; 122 123 124 125 // The connection used to perform the actual communication with the server. 126 private volatile com.unboundid.ldap.sdk.LDAPConnection conn; 127 128 // The default constraints that will be used for non-search operations. 129 private LDAPConstraints constraints; 130 131 // The set of controls returned from the last operation. 132 private LDAPControl[] responseControls; 133 134 // The default constraints that will be used for search operations. 135 private LDAPSearchConstraints searchConstraints; 136 137 // The socket factory for this connection. 138 private LDAPSocketFactory socketFactory; 139 140 // The DN last used to bind to the server. 141 private String authDN; 142 143 // The password last used to bind to the server. 144 private String authPW; 145 146 147 148 /** 149 * Creates a new LDAP connection which will use the default socket factory. 150 */ 151 public LDAPConnection() 152 { 153 this(null); 154 } 155 156 157 158 /** 159 * Creates a new LDAP connection which will use the provided socket factory. 160 * 161 * @param socketFactory The socket factory to use when creating the socket 162 * to use for communicating with the server. 163 */ 164 public LDAPConnection(final LDAPSocketFactory socketFactory) 165 { 166 this.socketFactory = socketFactory; 167 if (socketFactory == null) 168 { 169 conn = new com.unboundid.ldap.sdk.LDAPConnection(); 170 } 171 else 172 { 173 174 conn = new com.unboundid.ldap.sdk.LDAPConnection( 175 new LDAPToJavaSocketFactory(socketFactory)); 176 } 177 178 authDN = null; 179 authPW = null; 180 181 constraints = new LDAPConstraints(); 182 searchConstraints = new LDAPSearchConstraints(); 183 } 184 185 186 187 /** 188 * Closes the connection to the server if the client forgets to do so. 189 * 190 * @throws Throwable If a problem occurs. 191 */ 192 @Override() 193 protected void finalize() 194 throws Throwable 195 { 196 conn.close(); 197 198 super.finalize(); 199 } 200 201 202 203 /** 204 * Retrieves the {@link com.unboundid.ldap.sdk.LDAPConnection} object used to 205 * back this connection. 206 * 207 * @return The {@code com.unboundid.ldap.sdk.LDAPConnection} object used to 208 * back this connection. 209 */ 210 public com.unboundid.ldap.sdk.LDAPConnection getSDKConnection() 211 { 212 return conn; 213 } 214 215 216 217 /** 218 * Retrieves the address to which the connection is established. 219 * 220 * @return The address to which the connection is established. 221 */ 222 public String getHost() 223 { 224 return conn.getConnectedAddress(); 225 } 226 227 228 229 /** 230 * Retrieves the port to which the connection is established. 231 * 232 * @return The port to which the connection is established. 233 */ 234 public int getPort() 235 { 236 return conn.getConnectedPort(); 237 } 238 239 240 241 /** 242 * Retrieves the DN of the user that last authenticated on this connection. 243 * 244 * @return The DN of the user that last authenticated on this connection, 245 * or {@code null} if it is not available. 246 */ 247 public String getAuthenticationDN() 248 { 249 return authDN; 250 } 251 252 253 254 /** 255 * Retrieves the password of the user that last authenticated on this 256 * connection. 257 * 258 * @return The password of the user that last authenticated on this 259 * connection, or {@code null} if it is not available. 260 */ 261 public String getAuthenticationPassword() 262 { 263 return authPW; 264 } 265 266 267 268 /** 269 * Retrieves the maximum length of time to wait for the connection to be 270 * established, in seconds. 271 * 272 * @return The maximum length of time to wait for the connection to be 273 * established. 274 */ 275 public int getConnectTimeout() 276 { 277 final int connectTimeoutMillis = 278 conn.getConnectionOptions().getConnectTimeoutMillis(); 279 if (connectTimeoutMillis > 0) 280 { 281 return Math.max(1, (connectTimeoutMillis / 1000)); 282 } 283 else 284 { 285 return 0; 286 } 287 } 288 289 290 291 /** 292 * Specifies the maximum length of time to wait for the connection to be 293 * established, in seconds. 294 * 295 * @param timeout The maximum length of time to wait for the connection to 296 * be established. 297 */ 298 public void setConnectTimeout(final int timeout) 299 { 300 final LDAPConnectionOptions options = conn.getConnectionOptions(); 301 302 if (timeout > 0) 303 { 304 options.setConnectTimeoutMillis(1000 * timeout); 305 } 306 else 307 { 308 options.setConnectTimeoutMillis(0); 309 } 310 311 conn.setConnectionOptions(options); 312 } 313 314 315 316 /** 317 * Retrieves the socket factory for this LDAP connection, if specified. 318 * 319 * @return The socket factory for this LDAP connection, or {@code null} if 320 * none has been provided. 321 */ 322 public LDAPSocketFactory getSocketFactory() 323 { 324 return socketFactory; 325 } 326 327 328 329 /** 330 * Sets the socket factory for this LDAP connection. 331 * 332 * @param socketFactory The socket factory for this LDAP connection. 333 */ 334 public void setSocketFactory(final LDAPSocketFactory socketFactory) 335 { 336 this.socketFactory = socketFactory; 337 338 if (socketFactory == null) 339 { 340 conn.setSocketFactory(null); 341 } 342 else 343 { 344 conn.setSocketFactory(new LDAPToJavaSocketFactory(socketFactory)); 345 } 346 } 347 348 349 350 /** 351 * Retrieves the constraints for this connection. 352 * 353 * @return The constraints for this connection. 354 */ 355 public LDAPConstraints getConstraints() 356 { 357 return constraints; 358 } 359 360 361 362 /** 363 * Updates the constraints for this connection. 364 * 365 * @param constraints The constraints for this connection. 366 */ 367 public void setConstraints(final LDAPConstraints constraints) 368 { 369 if (constraints == null) 370 { 371 this.constraints = new LDAPConstraints(); 372 } 373 else 374 { 375 this.constraints = constraints; 376 } 377 } 378 379 380 381 /** 382 * Retrieves the search constraints for this connection. 383 * 384 * @return The search constraints for this connection. 385 */ 386 public LDAPSearchConstraints getSearchConstraints() 387 { 388 return searchConstraints; 389 } 390 391 392 393 /** 394 * Updates the search constraints for this connection. 395 * 396 * @param searchConstraints The search constraints for this connection. 397 */ 398 public void setSearchConstraints( 399 final LDAPSearchConstraints searchConstraints) 400 { 401 if (searchConstraints == null) 402 { 403 this.searchConstraints = new LDAPSearchConstraints(); 404 } 405 else 406 { 407 this.searchConstraints = searchConstraints; 408 } 409 } 410 411 412 413 /** 414 * Retrieves the response controls from the last operation processed on this 415 * connection. 416 * 417 * @return The response controls from the last operation processed on this 418 * connection, or {@code null} if there were none. 419 */ 420 public LDAPControl[] getResponseControls() 421 { 422 return responseControls; 423 } 424 425 426 427 /** 428 * Indicates whether this connection is currently established. 429 * 430 * @return {@code true} if this connection is currently established, or 431 * {@code false} if not. 432 */ 433 public boolean isConnected() 434 { 435 return conn.isConnected(); 436 } 437 438 439 440 /** 441 * Attempts to establish this connection with the provided information. 442 * 443 * @param host The address of the server to which the connection should be 444 * established. 445 * @param port The port of the server to which the connection should be 446 * established. 447 * 448 * @throws LDAPException If a problem occurs while attempting to establish 449 * this connection. 450 */ 451 public void connect(final String host, final int port) 452 throws LDAPException 453 { 454 authDN = null; 455 authPW = null; 456 responseControls = null; 457 458 try 459 { 460 conn.close(); 461 if (socketFactory == null) 462 { 463 conn = new com.unboundid.ldap.sdk.LDAPConnection(host, port); 464 } 465 else 466 { 467 468 conn = new com.unboundid.ldap.sdk.LDAPConnection( 469 new LDAPToJavaSocketFactory(socketFactory), host, port); 470 } 471 } 472 catch (final com.unboundid.ldap.sdk.LDAPException le) 473 { 474 debugException(le); 475 throw new LDAPException(le); 476 } 477 } 478 479 480 481 /** 482 * Attempts to establish and authenticate this connection with the provided 483 * information. 484 * 485 * @param host The address of the server to which the connection should 486 * be established. 487 * @param port The port of the server to which the connection should be 488 * established. 489 * @param dn The DN to use to bind to the server. 490 * @param password The password to use to bind to the server. 491 * 492 * @throws LDAPException If a problem occurs while attempting to establish 493 * or authenticate this connection. If an exception 494 * is thrown, then the connection will not be 495 * established. 496 */ 497 public void connect(final String host, final int port, final String dn, 498 final String password) 499 throws LDAPException 500 { 501 connect(3, host, port, dn, password, null); 502 } 503 504 505 506 /** 507 * Attempts to establish and authenticate this connection with the provided 508 * information. 509 * 510 * @param host The address of the server to which the connection 511 * should be established. 512 * @param port The port of the server to which the connection should 513 * be established. 514 * @param dn The DN to use to bind to the server. 515 * @param password The password to use to bind to the server. 516 * @param constraints The constraints to use when processing the bind. 517 * 518 * @throws LDAPException If a problem occurs while attempting to establish 519 * or authenticate this connection. If an exception 520 * is thrown, then the connection will not be 521 * established. 522 */ 523 public void connect(final String host, final int port, final String dn, 524 final String password, final LDAPConstraints constraints) 525 throws LDAPException 526 { 527 connect(3, host, port, dn, password, constraints); 528 } 529 530 531 532 /** 533 * Attempts to establish and authenticate this connection with the provided 534 * information. 535 * 536 * @param version The LDAP protocol version to use for the connection. 537 * This will be ignored, since this implementation only 538 * supports LDAPv3. 539 * @param host The address of the server to which the connection should 540 * be established. 541 * @param port The port of the server to which the connection should be 542 * established. 543 * @param dn The DN to use to bind to the server. 544 * @param password The password to use to bind to the server. 545 * 546 * @throws LDAPException If a problem occurs while attempting to establish 547 * or authenticate this connection. If an exception 548 * is thrown, then the connection will not be 549 * established. 550 */ 551 public void connect(final int version, final String host, final int port, 552 final String dn, final String password) 553 throws LDAPException 554 { 555 connect(version, host, port, dn, password, null); 556 } 557 558 559 560 /** 561 * Attempts to establish and authenticate this connection with the provided 562 * information. 563 * 564 * @param version The LDAP protocol version to use for the connection. 565 * This will be ignored, since this implementation only 566 * supports LDAPv3. 567 * @param host The address of the server to which the connection 568 * should be established. 569 * @param port The port of the server to which the connection should 570 * be established. 571 * @param dn The DN to use to bind to the server. 572 * @param password The password to use to bind to the server. 573 * @param constraints The constraints to use when processing the bind. 574 * 575 * @throws LDAPException If a problem occurs while attempting to establish 576 * or authenticate this connection. If an exception 577 * is thrown, then the connection will not be 578 * established. 579 */ 580 public void connect(final int version, final String host, final int port, 581 final String dn, final String password, 582 final LDAPConstraints constraints) 583 throws LDAPException 584 { 585 connect(host, port); 586 587 try 588 { 589 if ((dn != null) && (password != null)) 590 { 591 bind(version, dn, password, constraints); 592 } 593 } 594 catch (LDAPException le) 595 { 596 conn.close(); 597 throw le; 598 } 599 } 600 601 602 603 /** 604 * Unbinds and disconnects from the directory server. 605 * 606 * @throws LDAPException If a problem occurs. 607 */ 608 public void disconnect() 609 throws LDAPException 610 { 611 authDN = null; 612 authPW = null; 613 614 conn.close(); 615 if (socketFactory == null) 616 { 617 conn = new com.unboundid.ldap.sdk.LDAPConnection(); 618 } 619 else 620 { 621 622 conn = new com.unboundid.ldap.sdk.LDAPConnection( 623 new LDAPToJavaSocketFactory(socketFactory)); 624 } 625 } 626 627 628 629 /** 630 * Disconnects from the directory server and attempts to re-connect and 631 * re-authenticate. 632 * 633 * @throws LDAPException If a problem occurs. If an exception is thrown, 634 * the connection will have been closed. 635 */ 636 public void reconnect() 637 throws LDAPException 638 { 639 final String host = getHost(); 640 final int port = getPort(); 641 final String dn = authDN; 642 final String pw = authPW; 643 644 if ((dn == null) || (pw == null)) 645 { 646 connect(host, port); 647 } 648 else 649 { 650 connect(host, port, dn, pw); 651 } 652 } 653 654 655 656 /** 657 * Sends a request to abandon the request with the specified message ID. 658 * 659 * @param id The message ID of the operation to abandon. 660 * 661 * @throws LDAPException If a problem occurs while sending the request. 662 */ 663 public void abandon(final int id) 664 throws LDAPException 665 { 666 try 667 { 668 conn.abandon(InternalSDKHelper.createAsyncRequestID(id, conn), 669 getControls(null)); 670 } 671 catch (com.unboundid.ldap.sdk.LDAPException le) 672 { 673 debugException(le); 674 throw new LDAPException(le); 675 } 676 } 677 678 679 680 /** 681 * Sends a request to abandon the provided search operation. 682 * 683 * @param searchResults The search results object for the search to abandon. 684 * 685 * @throws LDAPException If a problem occurs while sending the request. 686 */ 687 public void abandon(final LDAPSearchResults searchResults) 688 throws LDAPException 689 { 690 try 691 { 692 final AsyncRequestID requestID = searchResults.getAsyncRequestID(); 693 if (requestID != null) 694 { 695 searchResults.setAbandoned(); 696 conn.abandon(requestID); 697 } 698 else 699 { 700 // This should never happen. 701 throw new LDAPException( 702 "The search request has not been sent to the server", 703 LDAPException.PARAM_ERROR); 704 } 705 } 706 catch (com.unboundid.ldap.sdk.LDAPException le) 707 { 708 debugException(le); 709 throw new LDAPException(le); 710 } 711 } 712 713 714 715 /** 716 * Adds the provided entry to the directory. 717 * 718 * @param entry The entry to be added. 719 * 720 * @throws LDAPException If a problem occurs while adding the entry. 721 */ 722 public void add(final LDAPEntry entry) 723 throws LDAPException 724 { 725 add(entry, null); 726 } 727 728 729 730 /** 731 * Adds the provided entry to the directory. 732 * 733 * @param entry The entry to be added. 734 * @param constraints The constraints to use for the add operation. 735 * 736 * @throws LDAPException If a problem occurs while adding the entry. 737 */ 738 public void add(final LDAPEntry entry, final LDAPConstraints constraints) 739 throws LDAPException 740 { 741 final AddRequest addRequest = new AddRequest(entry.toEntry()); 742 update(addRequest, constraints); 743 744 try 745 { 746 final LDAPResult result = conn.add(addRequest); 747 setResponseControls(result); 748 } 749 catch (com.unboundid.ldap.sdk.LDAPException le) 750 { 751 debugException(le); 752 setResponseControls(le); 753 throw new LDAPException(le); 754 } 755 } 756 757 758 759 760 /** 761 * Authenticates to the directory server using a simple bind with the provided 762 * information. 763 * 764 * @param dn The DN of the user for the bind. 765 * @param password The password to use for the bind. 766 * 767 * @throws LDAPException If the bind attempt fails. 768 */ 769 public void authenticate(final String dn, final String password) 770 throws LDAPException 771 { 772 bind(3, dn, password, null); 773 } 774 775 776 777 /** 778 * Authenticates to the directory server using a simple bind with the provided 779 * information. 780 * 781 * @param dn The DN of the user for the bind. 782 * @param password The password to use for the bind. 783 * @param constraints The constraints to use for the bind operation. 784 * 785 * @throws LDAPException If the bind attempt fails. 786 */ 787 public void authenticate(final String dn, final String password, 788 final LDAPConstraints constraints) 789 throws LDAPException 790 { 791 bind(3, dn, password, constraints); 792 } 793 794 795 796 /** 797 * Authenticates to the directory server using a simple bind with the provided 798 * information. 799 * 800 * @param version The LDAP protocol version to use. This will be ignored, 801 * since this implementation only supports LDAPv3. 802 * @param dn The DN of the user for the bind. 803 * @param password The password to use for the bind. 804 * 805 * @throws LDAPException If the bind attempt fails. 806 */ 807 public void authenticate(final int version, final String dn, 808 final String password) 809 throws LDAPException 810 { 811 bind(version, dn, password, null); 812 } 813 814 815 816 /** 817 * Authenticates to the directory server using a simple bind with the provided 818 * information. 819 * 820 * @param version The LDAP protocol version to use. This will be 821 * ignored, since this implementation only supports 822 * LDAPv3. 823 * @param dn The DN of the user for the bind. 824 * @param password The password to use for the bind. 825 * @param constraints The constraints to use for the bind operation. 826 * 827 * @throws LDAPException If the bind attempt fails. 828 */ 829 public void authenticate(final int version, final String dn, 830 final String password, 831 final LDAPConstraints constraints) 832 throws LDAPException 833 { 834 bind(version, dn, password, constraints); 835 } 836 837 838 839 /** 840 * Authenticates to the directory server using a simple bind with the provided 841 * information. 842 * 843 * @param dn The DN of the user for the bind. 844 * @param password The password to use for the bind. 845 * 846 * @throws LDAPException If the bind attempt fails. 847 */ 848 public void bind(final String dn, final String password) 849 throws LDAPException 850 { 851 bind(3, dn, password, null); 852 } 853 854 855 856 /** 857 * Authenticates to the directory server using a simple bind with the provided 858 * information. 859 * 860 * @param dn The DN of the user for the bind. 861 * @param password The password to use for the bind. 862 * @param constraints The constraints to use for the bind operation. 863 * 864 * @throws LDAPException If the bind attempt fails. 865 */ 866 public void bind(final String dn, final String password, 867 final LDAPConstraints constraints) 868 throws LDAPException 869 { 870 bind(3, dn, password, constraints); 871 } 872 873 874 875 /** 876 * Authenticates to the directory server using a simple bind with the provided 877 * information. 878 * 879 * @param version The LDAP protocol version to use. This will be ignored, 880 * since this implementation only supports LDAPv3. 881 * @param dn The DN of the user for the bind. 882 * @param password The password to use for the bind. 883 * 884 * @throws LDAPException If the bind attempt fails. 885 */ 886 public void bind(final int version, final String dn, final String password) 887 throws LDAPException 888 { 889 bind(version, dn, password, null); 890 } 891 892 893 894 /** 895 * Authenticates to the directory server using a simple bind with the provided 896 * information. 897 * 898 * @param version The LDAP protocol version to use. This will be 899 * ignored, since this implementation only supports 900 * LDAPv3. 901 * @param dn The DN of the user for the bind. 902 * @param password The password to use for the bind. 903 * @param constraints The constraints to use for the bind operation. 904 * 905 * @throws LDAPException If the bind attempt fails. 906 */ 907 public void bind(final int version, final String dn, final String password, 908 final LDAPConstraints constraints) 909 throws LDAPException 910 { 911 final SimpleBindRequest bindRequest = 912 new SimpleBindRequest(dn, password, getControls(constraints)); 913 authDN = null; 914 authPW = null; 915 916 try 917 { 918 final BindResult bindResult = conn.bind(bindRequest); 919 setResponseControls(bindResult); 920 if (bindResult.getResultCode() == ResultCode.SUCCESS) 921 { 922 authDN = dn; 923 authPW = password; 924 } 925 } 926 catch (com.unboundid.ldap.sdk.LDAPException le) 927 { 928 debugException(le); 929 setResponseControls(le); 930 throw new LDAPException(le); 931 } 932 } 933 934 935 936 /** 937 * Indicates whether the specified entry has the given attribute value. 938 * 939 * @param dn The DN of the entry to compare. 940 * @param attribute The attribute (which must have exactly one value) to use 941 * for the comparison. 942 * 943 * @return {@code true} if the compare matched the target entry, or 944 * {@code false} if not. 945 * 946 * @throws LDAPException If a problem occurs while processing the compare. 947 */ 948 public boolean compare(final String dn, final LDAPAttribute attribute) 949 throws LDAPException 950 { 951 return compare(dn, attribute, null); 952 } 953 954 955 956 /** 957 * Indicates whether the specified entry has the given attribute value. 958 * 959 * @param dn The DN of the entry to compare. 960 * @param attribute The attribute (which must have exactly one value) to 961 * use for the comparison. 962 * @param constraints The constraints to use for the compare operation. 963 * 964 * @return {@code true} if the compare matched the target entry, or 965 * {@code false} if not. 966 * 967 * @throws LDAPException If a problem occurs while processing the compare. 968 */ 969 public boolean compare(final String dn, final LDAPAttribute attribute, 970 final LDAPConstraints constraints) 971 throws LDAPException 972 { 973 final CompareRequest compareRequest = new CompareRequest(dn, 974 attribute.getName(), attribute.getByteValueArray()[0]); 975 update(compareRequest, constraints); 976 977 try 978 { 979 final CompareResult result = conn.compare(compareRequest); 980 setResponseControls(result); 981 return result.compareMatched(); 982 } 983 catch (com.unboundid.ldap.sdk.LDAPException le) 984 { 985 debugException(le); 986 setResponseControls(le); 987 throw new LDAPException(le); 988 } 989 } 990 991 992 993 /** 994 * Removes an entry from the directory. 995 * 996 * @param dn The DN of the entry to delete. 997 * 998 * @throws LDAPException If a problem occurs while processing the delete. 999 */ 1000 public void delete(final String dn) 1001 throws LDAPException 1002 { 1003 delete(dn, null); 1004 } 1005 1006 1007 1008 /** 1009 * Removes an entry from the directory. 1010 * 1011 * @param dn The DN of the entry to delete. 1012 * @param constraints The constraints to use for the delete operation. 1013 * 1014 * @throws LDAPException If a problem occurs while processing the delete. 1015 */ 1016 public void delete(final String dn, final LDAPConstraints constraints) 1017 throws LDAPException 1018 { 1019 final DeleteRequest deleteRequest = new DeleteRequest(dn); 1020 update(deleteRequest, constraints); 1021 1022 try 1023 { 1024 final LDAPResult result = conn.delete(deleteRequest); 1025 setResponseControls(result); 1026 } 1027 catch (com.unboundid.ldap.sdk.LDAPException le) 1028 { 1029 debugException(le); 1030 setResponseControls(le); 1031 throw new LDAPException(le); 1032 } 1033 } 1034 1035 1036 1037 /** 1038 * Processes an extended operation in the directory. 1039 * 1040 * @param extendedOperation The extended operation to process. 1041 * 1042 * @return The result returned from the extended operation. 1043 * 1044 * @throws LDAPException If a problem occurs while processing the operation. 1045 */ 1046 public LDAPExtendedOperation extendedOperation( 1047 final LDAPExtendedOperation extendedOperation) 1048 throws LDAPException 1049 { 1050 return extendedOperation(extendedOperation, null); 1051 } 1052 1053 1054 1055 /** 1056 * Processes an extended operation in the directory. 1057 * 1058 * @param extendedOperation The extended operation to process. 1059 * @param constraints The constraints to use for the operation. 1060 * 1061 * @return The result returned from the extended operation. 1062 * 1063 * @throws LDAPException If a problem occurs while processing the operation. 1064 */ 1065 public LDAPExtendedOperation extendedOperation( 1066 final LDAPExtendedOperation extendedOperation, 1067 final LDAPConstraints constraints) 1068 throws LDAPException 1069 { 1070 final ExtendedRequest extendedRequest = new ExtendedRequest( 1071 extendedOperation.getID(), 1072 new ASN1OctetString(extendedOperation.getValue()), 1073 getControls(constraints)); 1074 1075 try 1076 { 1077 final ExtendedResult result = 1078 conn.processExtendedOperation(extendedRequest); 1079 setResponseControls(result); 1080 1081 if (result.getResultCode() != ResultCode.SUCCESS) 1082 { 1083 throw new LDAPException(result.getDiagnosticMessage(), 1084 result.getResultCode().intValue(), result.getDiagnosticMessage(), 1085 result.getMatchedDN()); 1086 } 1087 1088 final byte[] valueBytes; 1089 final ASN1OctetString value = result.getValue(); 1090 if (value == null) 1091 { 1092 valueBytes = null; 1093 } 1094 else 1095 { 1096 valueBytes = value.getValue(); 1097 } 1098 1099 return new LDAPExtendedOperation(result.getOID(), valueBytes); 1100 } 1101 catch (com.unboundid.ldap.sdk.LDAPException le) 1102 { 1103 debugException(le); 1104 setResponseControls(le); 1105 throw new LDAPException(le); 1106 } 1107 } 1108 1109 1110 1111 /** 1112 * Modifies an entry in the directory. 1113 * 1114 * @param dn The DN of the entry to modify. 1115 * @param mod The modification to apply to the entry. 1116 * 1117 * @throws LDAPException If a problem occurs while processing the delete. 1118 */ 1119 public void modify(final String dn, final LDAPModification mod) 1120 throws LDAPException 1121 { 1122 modify(dn, new LDAPModification[] { mod }, null); 1123 } 1124 1125 1126 1127 /** 1128 * Modifies an entry in the directory. 1129 * 1130 * @param dn The DN of the entry to modify. 1131 * @param mods The modifications to apply to the entry. 1132 * 1133 * @throws LDAPException If a problem occurs while processing the delete. 1134 */ 1135 public void modify(final String dn, final LDAPModification[] mods) 1136 throws LDAPException 1137 { 1138 modify(dn, mods, null); 1139 } 1140 1141 1142 1143 /** 1144 * Modifies an entry in the directory. 1145 * 1146 * @param dn The DN of the entry to modify. 1147 * @param mod The modification to apply to the entry. 1148 * @param constraints The constraints to use for the modify operation. 1149 * 1150 * @throws LDAPException If a problem occurs while processing the delete. 1151 */ 1152 public void modify(final String dn, final LDAPModification mod, 1153 final LDAPConstraints constraints) 1154 throws LDAPException 1155 { 1156 modify(dn, new LDAPModification[] { mod }, constraints); 1157 } 1158 1159 1160 1161 /** 1162 * Modifies an entry in the directory. 1163 * 1164 * @param dn The DN of the entry to modify. 1165 * @param mods The modifications to apply to the entry. 1166 * @param constraints The constraints to use for the modify operation. 1167 * 1168 * @throws LDAPException If a problem occurs while processing the delete. 1169 */ 1170 public void modify(final String dn, final LDAPModification[] mods, 1171 final LDAPConstraints constraints) 1172 throws LDAPException 1173 { 1174 final Modification[] m = new Modification[mods.length]; 1175 for (int i=0; i < mods.length; i++) 1176 { 1177 m[i] = mods[i].toModification(); 1178 } 1179 1180 final ModifyRequest modifyRequest = new ModifyRequest(dn, m); 1181 update(modifyRequest, constraints); 1182 1183 try 1184 { 1185 final LDAPResult result = conn.modify(modifyRequest); 1186 setResponseControls(result); 1187 } 1188 catch (com.unboundid.ldap.sdk.LDAPException le) 1189 { 1190 debugException(le); 1191 setResponseControls(le); 1192 throw new LDAPException(le); 1193 } 1194 } 1195 1196 1197 1198 /** 1199 * Modifies an entry in the directory. 1200 * 1201 * @param dn The DN of the entry to modify. 1202 * @param mods The modifications to apply to the entry. 1203 * 1204 * @throws LDAPException If a problem occurs while processing the delete. 1205 */ 1206 public void modify(final String dn, final LDAPModificationSet mods) 1207 throws LDAPException 1208 { 1209 modify(dn, mods.toArray(), null); 1210 } 1211 1212 1213 1214 /** 1215 * Modifies an entry in the directory. 1216 * 1217 * @param dn The DN of the entry to modify. 1218 * @param mods The modifications to apply to the entry. 1219 * @param constraints The constraints to use for the modify operation. 1220 * 1221 * @throws LDAPException If a problem occurs while processing the delete. 1222 */ 1223 public void modify(final String dn, final LDAPModificationSet mods, 1224 final LDAPConstraints constraints) 1225 throws LDAPException 1226 { 1227 modify(dn, mods.toArray(), constraints); 1228 } 1229 1230 1231 1232 /** 1233 * Retrieves an entry from the directory server. 1234 * 1235 * @param dn The DN of the entry to retrieve. 1236 * 1237 * @return The entry that was read. 1238 * 1239 * @throws LDAPException If a problem occurs while performing the search. 1240 */ 1241 public LDAPEntry read(final String dn) 1242 throws LDAPException 1243 { 1244 return read(dn, null, null); 1245 } 1246 1247 1248 1249 /** 1250 * Retrieves an entry from the directory server. 1251 * 1252 * @param dn The DN of the entry to retrieve. 1253 * @param constraints The constraints to use for the search operation. 1254 * 1255 * @return The entry that was read. 1256 * 1257 * @throws LDAPException If a problem occurs while performing the search. 1258 */ 1259 public LDAPEntry read(final String dn, 1260 final LDAPSearchConstraints constraints) 1261 throws LDAPException 1262 { 1263 return read(dn, null, constraints); 1264 } 1265 1266 1267 1268 /** 1269 * Retrieves an entry from the directory server. 1270 * 1271 * @param dn The DN of the entry to retrieve. 1272 * @param attrs The set of attributes to request. 1273 * 1274 * @return The entry that was read. 1275 * 1276 * @throws LDAPException If a problem occurs while performing the search. 1277 */ 1278 public LDAPEntry read(final String dn, final String[] attrs) 1279 throws LDAPException 1280 { 1281 return read(dn, attrs, null); 1282 } 1283 1284 1285 1286 /** 1287 * Retrieves an entry from the directory server. 1288 * 1289 * @param dn The DN of the entry to retrieve. 1290 * @param attrs The set of attributes to request. 1291 * @param constraints The constraints to use for the search operation. 1292 * 1293 * @return The entry that was read. 1294 * 1295 * @throws LDAPException If a problem occurs while performing the search. 1296 */ 1297 public LDAPEntry read(final String dn, final String[] attrs, 1298 final LDAPSearchConstraints constraints) 1299 throws LDAPException 1300 { 1301 final Filter filter = Filter.createORFilter( 1302 Filter.createPresenceFilter("objectClass"), 1303 Filter.createEqualityFilter("objectClass", "ldapSubentry")); 1304 1305 final SearchRequest searchRequest = 1306 new SearchRequest(dn, SearchScope.BASE, filter, attrs); 1307 update(searchRequest, constraints); 1308 1309 try 1310 { 1311 final SearchResult searchResult = conn.search(searchRequest); 1312 setResponseControls(searchResult); 1313 1314 if (searchResult.getEntryCount() != 1) 1315 { 1316 throw new LDAPException(null, LDAPException.NO_RESULTS_RETURNED); 1317 } 1318 1319 return new LDAPEntry(searchResult.getSearchEntries().get(0)); 1320 } 1321 catch (com.unboundid.ldap.sdk.LDAPException le) 1322 { 1323 debugException(le); 1324 setResponseControls(le); 1325 throw new LDAPException(le); 1326 } 1327 } 1328 1329 1330 1331 /** 1332 * Alters the DN of an entry in the directory. 1333 * 1334 * @param dn The DN of the entry to modify. 1335 * @param newRDN The new RDN to use for the entry. 1336 * @param deleteOldRDN Indicates whether to remove the old RDN value(s). 1337 * 1338 * @throws LDAPException If a problem occurs while processing the delete. 1339 */ 1340 public void rename(final String dn, final String newRDN, 1341 final boolean deleteOldRDN) 1342 throws LDAPException 1343 { 1344 rename(dn, newRDN, null, deleteOldRDN, null); 1345 } 1346 1347 1348 1349 /** 1350 * Alters the DN of an entry in the directory. 1351 * 1352 * @param dn The DN of the entry to modify. 1353 * @param newRDN The new RDN to use for the entry. 1354 * @param deleteOldRDN Indicates whether to remove the old RDN value(s). 1355 * @param constraints The constraints to use for the modify operation. 1356 * 1357 * @throws LDAPException If a problem occurs while processing the delete. 1358 */ 1359 public void rename(final String dn, final String newRDN, 1360 final boolean deleteOldRDN, 1361 final LDAPConstraints constraints) 1362 throws LDAPException 1363 { 1364 rename(dn, newRDN, null, deleteOldRDN, constraints); 1365 } 1366 1367 1368 1369 /** 1370 * Alters the DN of an entry in the directory. 1371 * 1372 * @param dn The DN of the entry to modify. 1373 * @param newRDN The new RDN to use for the entry. 1374 * @param newParentDN The DN of the new parent, or {@code null} if it 1375 * should not be moved below a new parent. 1376 * @param deleteOldRDN Indicates whether to remove the old RDN value(s). 1377 * 1378 * @throws LDAPException If a problem occurs while processing the delete. 1379 */ 1380 public void rename(final String dn, final String newRDN, 1381 final String newParentDN, final boolean deleteOldRDN) 1382 throws LDAPException 1383 { 1384 rename(dn, newRDN, newParentDN, deleteOldRDN, null); 1385 } 1386 1387 1388 1389 /** 1390 * Alters the DN of an entry in the directory. 1391 * 1392 * @param dn The DN of the entry to modify. 1393 * @param newRDN The new RDN to use for the entry. 1394 * @param newParentDN The DN of the new parent, or {@code null} if it 1395 * should not be moved below a new parent. 1396 * @param deleteOldRDN Indicates whether to remove the old RDN value(s). 1397 * @param constraints The constraints to use for the modify operation. 1398 * 1399 * @throws LDAPException If a problem occurs while processing the delete. 1400 */ 1401 public void rename(final String dn, final String newRDN, 1402 final String newParentDN, final boolean deleteOldRDN, 1403 final LDAPConstraints constraints) 1404 throws LDAPException 1405 { 1406 final ModifyDNRequest modifyDNRequest = 1407 new ModifyDNRequest(dn, newRDN, deleteOldRDN, newParentDN); 1408 update(modifyDNRequest, constraints); 1409 1410 try 1411 { 1412 final LDAPResult result = conn.modifyDN(modifyDNRequest); 1413 setResponseControls(result); 1414 } 1415 catch (com.unboundid.ldap.sdk.LDAPException le) 1416 { 1417 debugException(le); 1418 setResponseControls(le); 1419 throw new LDAPException(le); 1420 } 1421 } 1422 1423 1424 1425 /** 1426 * Processes a search in the directory server. 1427 * 1428 * @param baseDN The base DN for the search. 1429 * @param scope The scope for the search. 1430 * @param filter The filter for the search. 1431 * @param attributes The set of attributes to request. 1432 * @param typesOnly Indicates whether to return attribute types only or 1433 * both types and values. 1434 * 1435 * @return The entry that was read. 1436 * 1437 * @throws LDAPException If a problem occurs while performing the search. 1438 */ 1439 public LDAPSearchResults search(final String baseDN, final int scope, 1440 final String filter, final String[] attributes, 1441 final boolean typesOnly) 1442 throws LDAPException 1443 { 1444 return search(baseDN, scope, filter, attributes, typesOnly, null); 1445 } 1446 1447 1448 1449 /** 1450 * Processes a search in the directory server. 1451 * 1452 * @param baseDN The base DN for the search. 1453 * @param scope The scope for the search. 1454 * @param filter The filter for the search. 1455 * @param attributes The set of attributes to request. 1456 * @param typesOnly Indicates whether to return attribute types only or 1457 * both types and values. 1458 * @param constraints The constraints to use for the search operation. 1459 * 1460 * @return The entry that was read. 1461 * 1462 * @throws LDAPException If a problem occurs while performing the search. 1463 */ 1464 public LDAPSearchResults search(final String baseDN, final int scope, 1465 final String filter, final String[] attributes, 1466 final boolean typesOnly, final LDAPSearchConstraints constraints) 1467 throws LDAPException 1468 { 1469 final LDAPSearchResults results; 1470 final LDAPSearchConstraints c = 1471 (constraints == null) ? searchConstraints : constraints; 1472 results = new LDAPSearchResults(c.getTimeLimit()); 1473 1474 try 1475 { 1476 final SearchRequest searchRequest = new SearchRequest(results, baseDN, 1477 SearchScope.valueOf(scope), filter, attributes); 1478 1479 searchRequest.setDerefPolicy( 1480 DereferencePolicy.valueOf(c.getDereference())); 1481 searchRequest.setSizeLimit(c.getMaxResults()); 1482 searchRequest.setTimeLimitSeconds(c.getServerTimeLimit()); 1483 searchRequest.setTypesOnly(typesOnly); 1484 1485 update(searchRequest, constraints); 1486 1487 results.setAsyncRequestID(conn.asyncSearch(searchRequest)); 1488 return results; 1489 } 1490 catch (com.unboundid.ldap.sdk.LDAPException le) 1491 { 1492 debugException(le); 1493 setResponseControls(le); 1494 throw new LDAPException(le); 1495 } 1496 } 1497 1498 1499 1500 /** 1501 * Retrieves the set of controls to use in a request. 1502 * 1503 * @param c The constraints to be applied. 1504 * 1505 * @return The set of controls to use in a request. 1506 */ 1507 private Control[] getControls(final LDAPConstraints c) 1508 { 1509 Control[] controls = null; 1510 if (c != null) 1511 { 1512 controls = LDAPControl.toControls(c.getServerControls()); 1513 } 1514 else if (constraints != null) 1515 { 1516 controls = LDAPControl.toControls(constraints.getServerControls()); 1517 } 1518 1519 if (controls == null) 1520 { 1521 return new Control[0]; 1522 } 1523 else 1524 { 1525 return controls; 1526 } 1527 } 1528 1529 1530 1531 /** 1532 * Updates the provided request to account for the given set of constraints. 1533 * 1534 * @param request The request to be updated. 1535 * @param constraints The constraints to be applied. 1536 */ 1537 private void update(final UpdatableLDAPRequest request, 1538 final LDAPConstraints constraints) 1539 { 1540 final LDAPConstraints c = 1541 (constraints == null) ? this.constraints : constraints; 1542 1543 request.setControls(LDAPControl.toControls(c.getServerControls())); 1544 request.setResponseTimeoutMillis(c.getTimeLimit()); 1545 request.setFollowReferrals(c.getReferrals()); 1546 } 1547 1548 1549 1550 /** 1551 * Sets the response controls for this connection. 1552 * 1553 * @param ldapResult The result containing the controls to use. 1554 */ 1555 private void setResponseControls(final LDAPResult ldapResult) 1556 { 1557 if (ldapResult.hasResponseControl()) 1558 { 1559 responseControls = 1560 LDAPControl.toLDAPControls(ldapResult.getResponseControls()); 1561 } 1562 else 1563 { 1564 responseControls = null; 1565 } 1566 } 1567 1568 1569 1570 /** 1571 * Sets the response controls for this connection. 1572 * 1573 * @param ldapException The exception containing the controls to use. 1574 */ 1575 private void setResponseControls( 1576 final com.unboundid.ldap.sdk.LDAPException ldapException) 1577 { 1578 if (ldapException.hasResponseControl()) 1579 { 1580 responseControls = 1581 LDAPControl.toLDAPControls(ldapException.getResponseControls()); 1582 } 1583 else 1584 { 1585 responseControls = null; 1586 } 1587 } 1588}