001/* 002 * Copyright 2009-2016 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2009-2016 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 volatile 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.close(); 460 if (socketFactory == null) 461 { 462 conn = new com.unboundid.ldap.sdk.LDAPConnection(host, port); 463 } 464 else 465 { 466 467 conn = new com.unboundid.ldap.sdk.LDAPConnection( 468 new LDAPToJavaSocketFactory(socketFactory), host, port); 469 } 470 } 471 catch (final com.unboundid.ldap.sdk.LDAPException le) 472 { 473 debugException(le); 474 throw new LDAPException(le); 475 } 476 } 477 478 479 480 /** 481 * Attempts to establish and authenticate this connection with the provided 482 * information. 483 * 484 * @param host The address of the server to which the connection should 485 * be established. 486 * @param port The port of the server to which the connection should be 487 * established. 488 * @param dn The DN to use to bind to the server. 489 * @param password The password to use to bind to the server. 490 * 491 * @throws LDAPException If a problem occurs while attempting to establish 492 * or authenticate this connection. If an exception 493 * is thrown, then the connection will not be 494 * established. 495 */ 496 public void connect(final String host, final int port, final String dn, 497 final String password) 498 throws LDAPException 499 { 500 connect(3, host, port, dn, password, null); 501 } 502 503 504 505 /** 506 * Attempts to establish and authenticate this connection with the provided 507 * information. 508 * 509 * @param host The address of the server to which the connection 510 * should be established. 511 * @param port The port of the server to which the connection should 512 * be established. 513 * @param dn The DN to use to bind to the server. 514 * @param password The password to use to bind to the server. 515 * @param constraints The constraints to use when processing the bind. 516 * 517 * @throws LDAPException If a problem occurs while attempting to establish 518 * or authenticate this connection. If an exception 519 * is thrown, then the connection will not be 520 * established. 521 */ 522 public void connect(final String host, final int port, final String dn, 523 final String password, final LDAPConstraints constraints) 524 throws LDAPException 525 { 526 connect(3, host, port, dn, password, constraints); 527 } 528 529 530 531 /** 532 * Attempts to establish and authenticate this connection with the provided 533 * information. 534 * 535 * @param version The LDAP protocol version to use for the connection. 536 * This will be ignored, since this implementation only 537 * supports LDAPv3. 538 * @param host The address of the server to which the connection should 539 * be established. 540 * @param port The port of the server to which the connection should be 541 * established. 542 * @param dn The DN to use to bind to the server. 543 * @param password The password to use to bind to the server. 544 * 545 * @throws LDAPException If a problem occurs while attempting to establish 546 * or authenticate this connection. If an exception 547 * is thrown, then the connection will not be 548 * established. 549 */ 550 public void connect(final int version, final String host, final int port, 551 final String dn, final String password) 552 throws LDAPException 553 { 554 connect(version, host, port, dn, password, null); 555 } 556 557 558 559 /** 560 * Attempts to establish and authenticate this connection with the provided 561 * information. 562 * 563 * @param version The LDAP protocol version to use for the connection. 564 * This will be ignored, since this implementation only 565 * supports LDAPv3. 566 * @param host The address of the server to which the connection 567 * should be established. 568 * @param port The port of the server to which the connection should 569 * be established. 570 * @param dn The DN to use to bind to the server. 571 * @param password The password to use to bind to the server. 572 * @param constraints The constraints to use when processing the bind. 573 * 574 * @throws LDAPException If a problem occurs while attempting to establish 575 * or authenticate this connection. If an exception 576 * is thrown, then the connection will not be 577 * established. 578 */ 579 public void connect(final int version, final String host, final int port, 580 final String dn, final String password, 581 final LDAPConstraints constraints) 582 throws LDAPException 583 { 584 connect(host, port); 585 586 try 587 { 588 if ((dn != null) && (password != null)) 589 { 590 bind(version, dn, password, constraints); 591 } 592 } 593 catch (LDAPException le) 594 { 595 conn.close(); 596 throw le; 597 } 598 } 599 600 601 602 /** 603 * Unbinds and disconnects from the directory server. 604 * 605 * @throws LDAPException If a problem occurs. 606 */ 607 public void disconnect() 608 throws LDAPException 609 { 610 authDN = null; 611 authPW = null; 612 613 conn.close(); 614 if (socketFactory == null) 615 { 616 conn = new com.unboundid.ldap.sdk.LDAPConnection(); 617 } 618 else 619 { 620 621 conn = new com.unboundid.ldap.sdk.LDAPConnection( 622 new LDAPToJavaSocketFactory(socketFactory)); 623 } 624 } 625 626 627 628 /** 629 * Disconnects from the directory server and attempts to re-connect and 630 * re-authenticate. 631 * 632 * @throws LDAPException If a problem occurs. If an exception is thrown, 633 * the connection will have been closed. 634 */ 635 public void reconnect() 636 throws LDAPException 637 { 638 final String host = getHost(); 639 final int port = getPort(); 640 final String dn = authDN; 641 final String pw = authPW; 642 643 if ((dn == null) || (pw == null)) 644 { 645 connect(host, port); 646 } 647 else 648 { 649 connect(host, port, dn, pw); 650 } 651 } 652 653 654 655 /** 656 * Sends a request to abandon the request with the specified message ID. 657 * 658 * @param id The message ID of the operation to abandon. 659 * 660 * @throws LDAPException If a problem occurs while sending the request. 661 */ 662 public void abandon(final int id) 663 throws LDAPException 664 { 665 try 666 { 667 conn.abandon(InternalSDKHelper.createAsyncRequestID(id, conn), 668 getControls(null)); 669 } 670 catch (com.unboundid.ldap.sdk.LDAPException le) 671 { 672 debugException(le); 673 throw new LDAPException(le); 674 } 675 } 676 677 678 679 /** 680 * Adds the provided entry to the directory. 681 * 682 * @param entry The entry to be added. 683 * 684 * @throws LDAPException If a problem occurs while adding the entry. 685 */ 686 public void add(final LDAPEntry entry) 687 throws LDAPException 688 { 689 add(entry, null); 690 } 691 692 693 694 /** 695 * Adds the provided entry to the directory. 696 * 697 * @param entry The entry to be added. 698 * @param constraints The constraints to use for the add operation. 699 * 700 * @throws LDAPException If a problem occurs while adding the entry. 701 */ 702 public void add(final LDAPEntry entry, final LDAPConstraints constraints) 703 throws LDAPException 704 { 705 final AddRequest addRequest = new AddRequest(entry.toEntry()); 706 update(addRequest, constraints); 707 708 try 709 { 710 final LDAPResult result = conn.add(addRequest); 711 setResponseControls(result); 712 } 713 catch (com.unboundid.ldap.sdk.LDAPException le) 714 { 715 debugException(le); 716 setResponseControls(le); 717 throw new LDAPException(le); 718 } 719 } 720 721 722 723 724 /** 725 * Authenticates to the directory server using a simple bind with the provided 726 * information. 727 * 728 * @param dn The DN of the user for the bind. 729 * @param password The password to use for the bind. 730 * 731 * @throws LDAPException If the bind attempt fails. 732 */ 733 public void authenticate(final String dn, final String password) 734 throws LDAPException 735 { 736 bind(3, dn, password, null); 737 } 738 739 740 741 /** 742 * Authenticates to the directory server using a simple bind with the provided 743 * information. 744 * 745 * @param dn The DN of the user for the bind. 746 * @param password The password to use for the bind. 747 * @param constraints The constraints to use for the bind operation. 748 * 749 * @throws LDAPException If the bind attempt fails. 750 */ 751 public void authenticate(final String dn, final String password, 752 final LDAPConstraints constraints) 753 throws LDAPException 754 { 755 bind(3, dn, password, constraints); 756 } 757 758 759 760 /** 761 * Authenticates to the directory server using a simple bind with the provided 762 * information. 763 * 764 * @param version The LDAP protocol version to use. This will be ignored, 765 * since this implementation only supports LDAPv3. 766 * @param dn The DN of the user for the bind. 767 * @param password The password to use for the bind. 768 * 769 * @throws LDAPException If the bind attempt fails. 770 */ 771 public void authenticate(final int version, final String dn, 772 final String password) 773 throws LDAPException 774 { 775 bind(version, dn, password, null); 776 } 777 778 779 780 /** 781 * Authenticates to the directory server using a simple bind with the provided 782 * information. 783 * 784 * @param version The LDAP protocol version to use. This will be 785 * ignored, since this implementation only supports 786 * LDAPv3. 787 * @param dn The DN of the user for the bind. 788 * @param password The password to use for the bind. 789 * @param constraints The constraints to use for the bind operation. 790 * 791 * @throws LDAPException If the bind attempt fails. 792 */ 793 public void authenticate(final int version, final String dn, 794 final String password, 795 final LDAPConstraints constraints) 796 throws LDAPException 797 { 798 bind(version, dn, password, constraints); 799 } 800 801 802 803 /** 804 * Authenticates to the directory server using a simple bind with the provided 805 * information. 806 * 807 * @param dn The DN of the user for the bind. 808 * @param password The password to use for the bind. 809 * 810 * @throws LDAPException If the bind attempt fails. 811 */ 812 public void bind(final String dn, final String password) 813 throws LDAPException 814 { 815 bind(3, dn, password, null); 816 } 817 818 819 820 /** 821 * Authenticates to the directory server using a simple bind with the provided 822 * information. 823 * 824 * @param dn The DN of the user for the bind. 825 * @param password The password to use for the bind. 826 * @param constraints The constraints to use for the bind operation. 827 * 828 * @throws LDAPException If the bind attempt fails. 829 */ 830 public void bind(final String dn, final String password, 831 final LDAPConstraints constraints) 832 throws LDAPException 833 { 834 bind(3, 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 version The LDAP protocol version to use. This will be ignored, 844 * since this implementation only supports LDAPv3. 845 * @param dn The DN of the user for the bind. 846 * @param password The password to use for the bind. 847 * 848 * @throws LDAPException If the bind attempt fails. 849 */ 850 public void bind(final int version, final String dn, final String password) 851 throws LDAPException 852 { 853 bind(version, dn, password, null); 854 } 855 856 857 858 /** 859 * Authenticates to the directory server using a simple bind with the provided 860 * information. 861 * 862 * @param version The LDAP protocol version to use. This will be 863 * ignored, since this implementation only supports 864 * LDAPv3. 865 * @param dn The DN of the user for the bind. 866 * @param password The password to use for the bind. 867 * @param constraints The constraints to use for the bind operation. 868 * 869 * @throws LDAPException If the bind attempt fails. 870 */ 871 public void bind(final int version, final String dn, final String password, 872 final LDAPConstraints constraints) 873 throws LDAPException 874 { 875 final SimpleBindRequest bindRequest = 876 new SimpleBindRequest(dn, password, getControls(constraints)); 877 authDN = null; 878 authPW = null; 879 880 try 881 { 882 final BindResult bindResult = conn.bind(bindRequest); 883 setResponseControls(bindResult); 884 if (bindResult.getResultCode() == ResultCode.SUCCESS) 885 { 886 authDN = dn; 887 authPW = password; 888 } 889 } 890 catch (com.unboundid.ldap.sdk.LDAPException le) 891 { 892 debugException(le); 893 setResponseControls(le); 894 throw new LDAPException(le); 895 } 896 } 897 898 899 900 /** 901 * Indicates whether the specified entry has the given attribute value. 902 * 903 * @param dn The DN of the entry to compare. 904 * @param attribute The attribute (which must have exactly one value) to use 905 * for the comparison. 906 * 907 * @return {@code true} if the compare matched the target entry, or 908 * {@code false} if not. 909 * 910 * @throws LDAPException If a problem occurs while processing the compare. 911 */ 912 public boolean compare(final String dn, final LDAPAttribute attribute) 913 throws LDAPException 914 { 915 return compare(dn, attribute, null); 916 } 917 918 919 920 /** 921 * Indicates whether the specified entry has the given attribute value. 922 * 923 * @param dn The DN of the entry to compare. 924 * @param attribute The attribute (which must have exactly one value) to 925 * use for the comparison. 926 * @param constraints The constraints to use for the compare operation. 927 * 928 * @return {@code true} if the compare matched the target entry, or 929 * {@code false} if not. 930 * 931 * @throws LDAPException If a problem occurs while processing the compare. 932 */ 933 public boolean compare(final String dn, final LDAPAttribute attribute, 934 final LDAPConstraints constraints) 935 throws LDAPException 936 { 937 final CompareRequest compareRequest = new CompareRequest(dn, 938 attribute.getName(), attribute.getByteValueArray()[0]); 939 update(compareRequest, constraints); 940 941 try 942 { 943 final CompareResult result = conn.compare(compareRequest); 944 setResponseControls(result); 945 return result.compareMatched(); 946 } 947 catch (com.unboundid.ldap.sdk.LDAPException le) 948 { 949 debugException(le); 950 setResponseControls(le); 951 throw new LDAPException(le); 952 } 953 } 954 955 956 957 /** 958 * Removes an entry from the directory. 959 * 960 * @param dn The DN of the entry to delete. 961 * 962 * @throws LDAPException If a problem occurs while processing the delete. 963 */ 964 public void delete(final String dn) 965 throws LDAPException 966 { 967 delete(dn, null); 968 } 969 970 971 972 /** 973 * Removes an entry from the directory. 974 * 975 * @param dn The DN of the entry to delete. 976 * @param constraints The constraints to use for the delete operation. 977 * 978 * @throws LDAPException If a problem occurs while processing the delete. 979 */ 980 public void delete(final String dn, final LDAPConstraints constraints) 981 throws LDAPException 982 { 983 final DeleteRequest deleteRequest = new DeleteRequest(dn); 984 update(deleteRequest, constraints); 985 986 try 987 { 988 final LDAPResult result = conn.delete(deleteRequest); 989 setResponseControls(result); 990 } 991 catch (com.unboundid.ldap.sdk.LDAPException le) 992 { 993 debugException(le); 994 setResponseControls(le); 995 throw new LDAPException(le); 996 } 997 } 998 999 1000 1001 /** 1002 * Processes an extended operation in the directory. 1003 * 1004 * @param extendedOperation The extended operation to process. 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 throws LDAPException 1013 { 1014 return extendedOperation(extendedOperation, null); 1015 } 1016 1017 1018 1019 /** 1020 * Processes an extended operation in the directory. 1021 * 1022 * @param extendedOperation The extended operation to process. 1023 * @param constraints The constraints to use for the operation. 1024 * 1025 * @return The result returned from the extended operation. 1026 * 1027 * @throws LDAPException If a problem occurs while processing the operation. 1028 */ 1029 public LDAPExtendedOperation extendedOperation( 1030 final LDAPExtendedOperation extendedOperation, 1031 final LDAPConstraints constraints) 1032 throws LDAPException 1033 { 1034 final ExtendedRequest extendedRequest = new ExtendedRequest( 1035 extendedOperation.getID(), 1036 new ASN1OctetString(extendedOperation.getValue()), 1037 getControls(constraints)); 1038 1039 try 1040 { 1041 final ExtendedResult result = 1042 conn.processExtendedOperation(extendedRequest); 1043 setResponseControls(result); 1044 1045 if (result.getResultCode() != ResultCode.SUCCESS) 1046 { 1047 throw new LDAPException(result.getDiagnosticMessage(), 1048 result.getResultCode().intValue(), result.getDiagnosticMessage(), 1049 result.getMatchedDN()); 1050 } 1051 1052 final byte[] valueBytes; 1053 final ASN1OctetString value = result.getValue(); 1054 if (value == null) 1055 { 1056 valueBytes = null; 1057 } 1058 else 1059 { 1060 valueBytes = value.getValue(); 1061 } 1062 1063 return new LDAPExtendedOperation(result.getOID(), valueBytes); 1064 } 1065 catch (com.unboundid.ldap.sdk.LDAPException le) 1066 { 1067 debugException(le); 1068 setResponseControls(le); 1069 throw new LDAPException(le); 1070 } 1071 } 1072 1073 1074 1075 /** 1076 * Modifies an entry in the directory. 1077 * 1078 * @param dn The DN of the entry to modify. 1079 * @param mod The modification to apply to the entry. 1080 * 1081 * @throws LDAPException If a problem occurs while processing the delete. 1082 */ 1083 public void modify(final String dn, final LDAPModification mod) 1084 throws LDAPException 1085 { 1086 modify(dn, new LDAPModification[] { mod }, null); 1087 } 1088 1089 1090 1091 /** 1092 * Modifies an entry in the directory. 1093 * 1094 * @param dn The DN of the entry to modify. 1095 * @param mods The modifications to apply to the entry. 1096 * 1097 * @throws LDAPException If a problem occurs while processing the delete. 1098 */ 1099 public void modify(final String dn, final LDAPModification[] mods) 1100 throws LDAPException 1101 { 1102 modify(dn, mods, null); 1103 } 1104 1105 1106 1107 /** 1108 * Modifies an entry in the directory. 1109 * 1110 * @param dn The DN of the entry to modify. 1111 * @param mod The modification to apply to the entry. 1112 * @param constraints The constraints to use for the modify operation. 1113 * 1114 * @throws LDAPException If a problem occurs while processing the delete. 1115 */ 1116 public void modify(final String dn, final LDAPModification mod, 1117 final LDAPConstraints constraints) 1118 throws LDAPException 1119 { 1120 modify(dn, new LDAPModification[] { mod }, constraints); 1121 } 1122 1123 1124 1125 /** 1126 * Modifies an entry in the directory. 1127 * 1128 * @param dn The DN of the entry to modify. 1129 * @param mods The modifications to apply to the entry. 1130 * @param constraints The constraints to use for the modify operation. 1131 * 1132 * @throws LDAPException If a problem occurs while processing the delete. 1133 */ 1134 public void modify(final String dn, final LDAPModification[] mods, 1135 final LDAPConstraints constraints) 1136 throws LDAPException 1137 { 1138 final Modification[] m = new Modification[mods.length]; 1139 for (int i=0; i < mods.length; i++) 1140 { 1141 m[i] = mods[i].toModification(); 1142 } 1143 1144 final ModifyRequest modifyRequest = new ModifyRequest(dn, m); 1145 update(modifyRequest, constraints); 1146 1147 try 1148 { 1149 final LDAPResult result = conn.modify(modifyRequest); 1150 setResponseControls(result); 1151 } 1152 catch (com.unboundid.ldap.sdk.LDAPException le) 1153 { 1154 debugException(le); 1155 setResponseControls(le); 1156 throw new LDAPException(le); 1157 } 1158 } 1159 1160 1161 1162 /** 1163 * Modifies an entry in the directory. 1164 * 1165 * @param dn The DN of the entry to modify. 1166 * @param mods The modifications to apply to the entry. 1167 * 1168 * @throws LDAPException If a problem occurs while processing the delete. 1169 */ 1170 public void modify(final String dn, final LDAPModificationSet mods) 1171 throws LDAPException 1172 { 1173 modify(dn, mods.toArray(), null); 1174 } 1175 1176 1177 1178 /** 1179 * Modifies an entry in the directory. 1180 * 1181 * @param dn The DN of the entry to modify. 1182 * @param mods The modifications to apply to the entry. 1183 * @param constraints The constraints to use for the modify operation. 1184 * 1185 * @throws LDAPException If a problem occurs while processing the delete. 1186 */ 1187 public void modify(final String dn, final LDAPModificationSet mods, 1188 final LDAPConstraints constraints) 1189 throws LDAPException 1190 { 1191 modify(dn, mods.toArray(), constraints); 1192 } 1193 1194 1195 1196 /** 1197 * Retrieves an entry from the directory server. 1198 * 1199 * @param dn The DN of the entry to retrieve. 1200 * 1201 * @return The entry that was read. 1202 * 1203 * @throws LDAPException If a problem occurs while performing the search. 1204 */ 1205 public LDAPEntry read(final String dn) 1206 throws LDAPException 1207 { 1208 return read(dn, null, null); 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 constraints The constraints to use for the search operation. 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, 1224 final LDAPSearchConstraints constraints) 1225 throws LDAPException 1226 { 1227 return read(dn, null, 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 * @param attrs The set of attributes to request. 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 throws LDAPException 1244 { 1245 return read(dn, attrs, null); 1246 } 1247 1248 1249 1250 /** 1251 * Retrieves an entry from the directory server. 1252 * 1253 * @param dn The DN of the entry to retrieve. 1254 * @param attrs The set of attributes to request. 1255 * @param constraints The constraints to use for the search operation. 1256 * 1257 * @return The entry that was read. 1258 * 1259 * @throws LDAPException If a problem occurs while performing the search. 1260 */ 1261 public LDAPEntry read(final String dn, final String[] attrs, 1262 final LDAPSearchConstraints constraints) 1263 throws LDAPException 1264 { 1265 final Filter filter = Filter.createORFilter( 1266 Filter.createPresenceFilter("objectClass"), 1267 Filter.createEqualityFilter("objectClass", "ldapSubentry")); 1268 1269 final SearchRequest searchRequest = 1270 new SearchRequest(dn, SearchScope.BASE, filter, attrs); 1271 update(searchRequest, constraints); 1272 1273 try 1274 { 1275 final SearchResult searchResult = conn.search(searchRequest); 1276 setResponseControls(searchResult); 1277 1278 if (searchResult.getEntryCount() != 1) 1279 { 1280 throw new LDAPException(null, LDAPException.NO_RESULTS_RETURNED); 1281 } 1282 1283 return new LDAPEntry(searchResult.getSearchEntries().get(0)); 1284 } 1285 catch (com.unboundid.ldap.sdk.LDAPException le) 1286 { 1287 debugException(le); 1288 setResponseControls(le); 1289 throw new LDAPException(le); 1290 } 1291 } 1292 1293 1294 1295 /** 1296 * Alters the DN of an entry in the directory. 1297 * 1298 * @param dn The DN of the entry to modify. 1299 * @param newRDN The new RDN to use for the entry. 1300 * @param deleteOldRDN Indicates whether to remove the old RDN value(s). 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 throws LDAPException 1307 { 1308 rename(dn, newRDN, null, deleteOldRDN, null); 1309 } 1310 1311 1312 1313 /** 1314 * Alters the DN of an entry in the directory. 1315 * 1316 * @param dn The DN of the entry to modify. 1317 * @param newRDN The new RDN to use for the entry. 1318 * @param deleteOldRDN Indicates whether to remove the old RDN value(s). 1319 * @param constraints The constraints to use for the modify operation. 1320 * 1321 * @throws LDAPException If a problem occurs while processing the delete. 1322 */ 1323 public void rename(final String dn, final String newRDN, 1324 final boolean deleteOldRDN, 1325 final LDAPConstraints constraints) 1326 throws LDAPException 1327 { 1328 rename(dn, newRDN, null, deleteOldRDN, constraints); 1329 } 1330 1331 1332 1333 /** 1334 * Alters the DN of an entry in the directory. 1335 * 1336 * @param dn The DN of the entry to modify. 1337 * @param newRDN The new RDN to use for the entry. 1338 * @param newParentDN The DN of the new parent, or {@code null} if it 1339 * should not be moved below a new parent. 1340 * @param deleteOldRDN Indicates whether to remove the old RDN value(s). 1341 * 1342 * @throws LDAPException If a problem occurs while processing the delete. 1343 */ 1344 public void rename(final String dn, final String newRDN, 1345 final String newParentDN, final boolean deleteOldRDN) 1346 throws LDAPException 1347 { 1348 rename(dn, newRDN, newParentDN, deleteOldRDN, null); 1349 } 1350 1351 1352 1353 /** 1354 * Alters the DN of an entry in the directory. 1355 * 1356 * @param dn The DN of the entry to modify. 1357 * @param newRDN The new RDN to use for the entry. 1358 * @param newParentDN The DN of the new parent, or {@code null} if it 1359 * should not be moved below a new parent. 1360 * @param deleteOldRDN Indicates whether to remove the old RDN value(s). 1361 * @param constraints The constraints to use for the modify operation. 1362 * 1363 * @throws LDAPException If a problem occurs while processing the delete. 1364 */ 1365 public void rename(final String dn, final String newRDN, 1366 final String newParentDN, final boolean deleteOldRDN, 1367 final LDAPConstraints constraints) 1368 throws LDAPException 1369 { 1370 final ModifyDNRequest modifyDNRequest = 1371 new ModifyDNRequest(dn, newRDN, deleteOldRDN, newParentDN); 1372 update(modifyDNRequest, constraints); 1373 1374 try 1375 { 1376 final LDAPResult result = conn.modifyDN(modifyDNRequest); 1377 setResponseControls(result); 1378 } 1379 catch (com.unboundid.ldap.sdk.LDAPException le) 1380 { 1381 debugException(le); 1382 setResponseControls(le); 1383 throw new LDAPException(le); 1384 } 1385 } 1386 1387 1388 1389 /** 1390 * Processes a search in the directory server. 1391 * 1392 * @param baseDN The base DN for the search. 1393 * @param scope The scope for the search. 1394 * @param filter The filter for the search. 1395 * @param attributes The set of attributes to request. 1396 * @param typesOnly Indicates whether to return attribute types only or 1397 * both types and values. 1398 * 1399 * @return The entry that was read. 1400 * 1401 * @throws LDAPException If a problem occurs while performing the search. 1402 */ 1403 public LDAPSearchResults search(final String baseDN, final int scope, 1404 final String filter, final String[] attributes, 1405 final boolean typesOnly) 1406 throws LDAPException 1407 { 1408 return search(baseDN, scope, filter, attributes, typesOnly, null); 1409 } 1410 1411 1412 1413 /** 1414 * Processes a search in the directory server. 1415 * 1416 * @param baseDN The base DN for the search. 1417 * @param scope The scope for the search. 1418 * @param filter The filter for the search. 1419 * @param attributes The set of attributes to request. 1420 * @param typesOnly Indicates whether to return attribute types only or 1421 * both types and values. 1422 * @param constraints The constraints to use for the search operation. 1423 * 1424 * @return The entry that was read. 1425 * 1426 * @throws LDAPException If a problem occurs while performing the search. 1427 */ 1428 public LDAPSearchResults search(final String baseDN, final int scope, 1429 final String filter, final String[] attributes, 1430 final boolean typesOnly, final LDAPSearchConstraints constraints) 1431 throws LDAPException 1432 { 1433 final LDAPSearchResults results; 1434 final LDAPSearchConstraints c = 1435 (constraints == null) ? searchConstraints : constraints; 1436 results = new LDAPSearchResults(c.getTimeLimit()); 1437 1438 try 1439 { 1440 final SearchRequest searchRequest = new SearchRequest(results, baseDN, 1441 SearchScope.valueOf(scope), filter, attributes); 1442 1443 searchRequest.setDerefPolicy( 1444 DereferencePolicy.valueOf(c.getDereference())); 1445 searchRequest.setSizeLimit(c.getMaxResults()); 1446 searchRequest.setTimeLimitSeconds(c.getServerTimeLimit()); 1447 searchRequest.setTypesOnly(typesOnly); 1448 1449 update(searchRequest, constraints); 1450 1451 conn.asyncSearch(searchRequest); 1452 return results; 1453 } 1454 catch (com.unboundid.ldap.sdk.LDAPException le) 1455 { 1456 debugException(le); 1457 setResponseControls(le); 1458 throw new LDAPException(le); 1459 } 1460 } 1461 1462 1463 1464 /** 1465 * Retrieves the set of controls to use in a request. 1466 * 1467 * @param c The constraints to be applied. 1468 * 1469 * @return The set of controls to use in a request. 1470 */ 1471 private Control[] getControls(final LDAPConstraints c) 1472 { 1473 Control[] controls = null; 1474 if (c != null) 1475 { 1476 controls = LDAPControl.toControls(c.getServerControls()); 1477 } 1478 else if (constraints != null) 1479 { 1480 controls = LDAPControl.toControls(constraints.getServerControls()); 1481 } 1482 1483 if (controls == null) 1484 { 1485 return new Control[0]; 1486 } 1487 else 1488 { 1489 return controls; 1490 } 1491 } 1492 1493 1494 1495 /** 1496 * Updates the provided request to account for the given set of constraints. 1497 * 1498 * @param request The request to be updated. 1499 * @param constraints The constraints to be applied. 1500 */ 1501 private void update(final UpdatableLDAPRequest request, 1502 final LDAPConstraints constraints) 1503 { 1504 final LDAPConstraints c = 1505 (constraints == null) ? this.constraints : constraints; 1506 1507 request.setControls(LDAPControl.toControls(c.getServerControls())); 1508 request.setResponseTimeoutMillis(c.getTimeLimit()); 1509 request.setFollowReferrals(c.getReferrals()); 1510 } 1511 1512 1513 1514 /** 1515 * Sets the response controls for this connection. 1516 * 1517 * @param ldapResult The result containing the controls to use. 1518 */ 1519 private void setResponseControls(final LDAPResult ldapResult) 1520 { 1521 if (ldapResult.hasResponseControl()) 1522 { 1523 responseControls = 1524 LDAPControl.toLDAPControls(ldapResult.getResponseControls()); 1525 } 1526 else 1527 { 1528 responseControls = null; 1529 } 1530 } 1531 1532 1533 1534 /** 1535 * Sets the response controls for this connection. 1536 * 1537 * @param ldapException The exception containing the controls to use. 1538 */ 1539 private void setResponseControls( 1540 final com.unboundid.ldap.sdk.LDAPException ldapException) 1541 { 1542 if (ldapException.hasResponseControl()) 1543 { 1544 responseControls = 1545 LDAPControl.toLDAPControls(ldapException.getResponseControls()); 1546 } 1547 else 1548 { 1549 responseControls = null; 1550 } 1551 } 1552}