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