001/* 002 * Copyright 2007-2026 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2007-2026 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2007-2026 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk; 037 038 039 040import java.util.ArrayList; 041import java.util.Arrays; 042import java.util.List; 043import java.util.concurrent.LinkedBlockingQueue; 044import java.util.concurrent.TimeUnit; 045import java.util.logging.Level; 046 047import com.unboundid.asn1.ASN1Buffer; 048import com.unboundid.asn1.ASN1BufferSequence; 049import com.unboundid.asn1.ASN1Element; 050import com.unboundid.asn1.ASN1Integer; 051import com.unboundid.asn1.ASN1OctetString; 052import com.unboundid.asn1.ASN1Sequence; 053import com.unboundid.ldap.protocol.LDAPMessage; 054import com.unboundid.ldap.protocol.LDAPResponse; 055import com.unboundid.ldap.protocol.ProtocolOp; 056import com.unboundid.util.Debug; 057import com.unboundid.util.InternalUseOnly; 058import com.unboundid.util.LDAPSDKUsageException; 059import com.unboundid.util.NotMutable; 060import com.unboundid.util.NotNull; 061import com.unboundid.util.Nullable; 062import com.unboundid.util.StaticUtils; 063import com.unboundid.util.ThreadSafety; 064import com.unboundid.util.ThreadSafetyLevel; 065 066import static com.unboundid.ldap.sdk.LDAPMessages.*; 067 068 069 070/** 071 * This class implements the processing necessary to perform an LDAPv3 simple 072 * bind operation, which authenticates using a bind DN and password. 073 */ 074@NotMutable() 075@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 076public final class SimpleBindRequest 077 extends BindRequest 078 implements ResponseAcceptor, ProtocolOp 079{ 080 /** 081 * The BER type to use for the credentials element in a simple bind request 082 * protocol op. 083 */ 084 private static final byte CRED_TYPE_SIMPLE = (byte) 0x80; 085 086 087 088 /** 089 * The ASN.1 octet string that will be used for the bind DN if none was 090 * provided. 091 */ 092 @NotNull private static final ASN1OctetString NO_BIND_DN = 093 new ASN1OctetString(); 094 095 096 097 /** 098 * The ASN.1 octet string that will be used for the bind password if none was 099 * provided. 100 */ 101 @NotNull private static final ASN1OctetString NO_PASSWORD = 102 new ASN1OctetString(CRED_TYPE_SIMPLE); 103 104 105 106 /** 107 * The serial version UID for this serializable class. 108 */ 109 private static final long serialVersionUID = 4725871243149974407L; 110 111 112 113 // The message ID from the last LDAP message sent from this request. 114 private int messageID = -1; 115 116 // The bind DN for this simple bind request. 117 @NotNull private final ASN1OctetString bindDN; 118 119 // The password for this simple bind request. 120 @Nullable private final ASN1OctetString password; 121 122 // The queue that will be used to receive response messages from the server. 123 @NotNull private final LinkedBlockingQueue<LDAPResponse> responseQueue = 124 new LinkedBlockingQueue<>(); 125 126 // The password provider that should be used to obtain the password for this 127 // simple bind request. 128 @Nullable private final PasswordProvider passwordProvider; 129 130 131 132 /** 133 * Creates a new simple bind request that may be used to perform an anonymous 134 * bind to the directory server (i.e., with a zero-length bind DN and a 135 * zero-length password). 136 */ 137 public SimpleBindRequest() 138 { 139 this(NO_BIND_DN, NO_PASSWORD, null, NO_CONTROLS); 140 } 141 142 143 144 /** 145 * Creates a new simple bind request with the provided bind DN and password. 146 * 147 * @param bindDN The bind DN for this simple bind request. 148 * @param password The password for this simple bind request. 149 */ 150 public SimpleBindRequest(@Nullable final String bindDN, 151 @Nullable final String password) 152 { 153 this(bindDN, password, NO_CONTROLS); 154 } 155 156 157 158 /** 159 * Creates a new simple bind request with the provided bind DN and password. 160 * 161 * @param bindDN The bind DN for this simple bind request. 162 * @param password The password for this simple bind request. 163 */ 164 public SimpleBindRequest(@Nullable final String bindDN, 165 @Nullable final byte[] password) 166 { 167 this(bindDN, password, NO_CONTROLS); 168 } 169 170 171 172 /** 173 * Creates a new simple bind request with the provided bind DN and password. 174 * 175 * @param bindDN The bind DN for this simple bind request. 176 * @param password The password for this simple bind request. 177 */ 178 public SimpleBindRequest(@Nullable final DN bindDN, 179 @Nullable final String password) 180 { 181 this(bindDN, password, NO_CONTROLS); 182 } 183 184 185 186 /** 187 * Creates a new simple bind request with the provided bind DN and password. 188 * 189 * @param bindDN The bind DN for this simple bind request. 190 * @param password The password for this simple bind request. 191 */ 192 public SimpleBindRequest(@Nullable final DN bindDN, 193 @Nullable final byte[] password) 194 { 195 this(bindDN, password, NO_CONTROLS); 196 } 197 198 199 200 /** 201 * Creates a new simple bind request with the provided bind DN and password. 202 * 203 * @param bindDN The bind DN for this simple bind request. 204 * @param password The password for this simple bind request. 205 * @param controls The set of controls for this simple bind request. 206 */ 207 public SimpleBindRequest(@Nullable final String bindDN, 208 @Nullable final String password, 209 @Nullable final Control... controls) 210 { 211 super(controls); 212 213 if (bindDN == null) 214 { 215 this.bindDN = NO_BIND_DN; 216 } 217 else 218 { 219 this.bindDN = new ASN1OctetString(bindDN); 220 } 221 222 if (password == null) 223 { 224 this.password = NO_PASSWORD; 225 } 226 else 227 { 228 this.password = new ASN1OctetString(CRED_TYPE_SIMPLE, password); 229 } 230 231 passwordProvider = null; 232 } 233 234 235 236 /** 237 * Creates a new simple bind request with the provided bind DN and password. 238 * 239 * @param bindDN The bind DN for this simple bind request. 240 * @param password The password for this simple bind request. 241 * @param controls The set of controls for this simple bind request. 242 */ 243 public SimpleBindRequest(@Nullable final String bindDN, 244 @Nullable final byte[] password, 245 @Nullable final Control... controls) 246 { 247 super(controls); 248 249 if (bindDN == null) 250 { 251 this.bindDN = NO_BIND_DN; 252 } 253 else 254 { 255 this.bindDN = new ASN1OctetString(bindDN); 256 } 257 258 if (password == null) 259 { 260 this.password = NO_PASSWORD; 261 } 262 else 263 { 264 this.password = new ASN1OctetString(CRED_TYPE_SIMPLE, password); 265 } 266 267 passwordProvider = null; 268 } 269 270 271 272 /** 273 * Creates a new simple bind request with the provided bind DN and password. 274 * 275 * @param bindDN The bind DN for this simple bind request. 276 * @param password The password for this simple bind request. 277 * @param controls The set of controls for this simple bind request. 278 */ 279 public SimpleBindRequest(@Nullable final DN bindDN, 280 @Nullable final String password, 281 @Nullable final Control... controls) 282 { 283 super(controls); 284 285 if (bindDN == null) 286 { 287 this.bindDN = NO_BIND_DN; 288 } 289 else 290 { 291 this.bindDN = new ASN1OctetString(bindDN.toString()); 292 } 293 294 if (password == null) 295 { 296 this.password = NO_PASSWORD; 297 } 298 else 299 { 300 this.password = new ASN1OctetString(CRED_TYPE_SIMPLE, password); 301 } 302 303 passwordProvider = null; 304 } 305 306 307 308 /** 309 * Creates a new simple bind request with the provided bind DN and password. 310 * 311 * @param bindDN The bind DN for this simple bind request. 312 * @param password The password for this simple bind request. 313 * @param controls The set of controls for this simple bind request. 314 */ 315 public SimpleBindRequest(@Nullable final DN bindDN, 316 @Nullable final byte[] password, 317 @Nullable final Control... controls) 318 { 319 super(controls); 320 321 if (bindDN == null) 322 { 323 this.bindDN = NO_BIND_DN; 324 } 325 else 326 { 327 this.bindDN = new ASN1OctetString(bindDN.toString()); 328 } 329 330 if (password == null) 331 { 332 this.password = NO_PASSWORD; 333 } 334 else 335 { 336 this.password = new ASN1OctetString(CRED_TYPE_SIMPLE, password); 337 } 338 339 passwordProvider = null; 340 } 341 342 343 344 /** 345 * Creates a new simple bind request with the provided bind DN and that will 346 * use a password provider in order to obtain the bind password. 347 * 348 * @param bindDN The bind DN for this simple bind request. It 349 * must not be {@code null}. 350 * @param passwordProvider The password provider that will be used to obtain 351 * the password for this simple bind request. It 352 * must not be {@code null}. 353 * @param controls The set of controls for this simple bind request. 354 */ 355 public SimpleBindRequest(@NotNull final String bindDN, 356 @NotNull final PasswordProvider passwordProvider, 357 @Nullable final Control... controls) 358 { 359 super(controls); 360 361 this.bindDN = new ASN1OctetString(bindDN); 362 this.passwordProvider = passwordProvider; 363 364 password = null; 365 } 366 367 368 369 /** 370 * Creates a new simple bind request with the provided bind DN and that will 371 * use a password provider in order to obtain the bind password. 372 * 373 * @param bindDN The bind DN for this simple bind request. It 374 * must not be {@code null}. 375 * @param passwordProvider The password provider that will be used to obtain 376 * the password for this simple bind request. It 377 * must not be {@code null}. 378 * @param controls The set of controls for this simple bind request. 379 */ 380 public SimpleBindRequest(@NotNull final DN bindDN, 381 @NotNull final PasswordProvider passwordProvider, 382 @Nullable final Control... controls) 383 { 384 super(controls); 385 386 this.bindDN = new ASN1OctetString(bindDN.toString()); 387 this.passwordProvider = passwordProvider; 388 389 password = null; 390 } 391 392 393 394 /** 395 * Creates a new simple bind request with the provided bind DN and password. 396 * 397 * @param bindDN The bind DN for this simple bind request. 398 * @param password The password for this simple bind request. 399 * @param passwordProvider The password provider that will be used to obtain 400 * the password to use for the bind request. 401 * @param controls The set of controls for this simple bind request. 402 */ 403 private SimpleBindRequest(@Nullable final ASN1OctetString bindDN, 404 @Nullable final ASN1OctetString password, 405 @Nullable final PasswordProvider passwordProvider, 406 @Nullable final Control... controls) 407 { 408 super(controls); 409 410 this.bindDN = bindDN; 411 this.password = password; 412 this.passwordProvider = passwordProvider; 413 } 414 415 416 417 /** 418 * Retrieves the bind DN for this simple bind request. 419 * 420 * @return The bind DN for this simple bind request. 421 */ 422 @NotNull() 423 public String getBindDN() 424 { 425 return bindDN.stringValue(); 426 } 427 428 429 430 /** 431 * Retrieves the password for this simple bind request, if no password 432 * provider has been configured. 433 * 434 * @return The password for this simple bind request, or {@code null} if a 435 * password provider will be used to obtain the password. 436 */ 437 @Nullable() 438 public ASN1OctetString getPassword() 439 { 440 return password; 441 } 442 443 444 445 /** 446 * Retrieves the password provider for this simple bind request, if defined. 447 * 448 * @return The password provider for this simple bind request, or 449 * {@code null} if this bind request was created with an explicit 450 * password rather than a password provider. 451 */ 452 @Nullable() 453 public PasswordProvider getPasswordProvider() 454 { 455 return passwordProvider; 456 } 457 458 459 460 /** 461 * {@inheritDoc} 462 */ 463 @Override() 464 public byte getProtocolOpType() 465 { 466 return LDAPMessage.PROTOCOL_OP_TYPE_BIND_REQUEST; 467 } 468 469 470 471 /** 472 * {@inheritDoc} 473 */ 474 @Override() 475 public void writeTo(@NotNull final ASN1Buffer buffer) 476 { 477 final ASN1BufferSequence requestSequence = 478 buffer.beginSequence(LDAPMessage.PROTOCOL_OP_TYPE_BIND_REQUEST); 479 buffer.addElement(VERSION_ELEMENT); 480 buffer.addElement(bindDN); 481 482 if (passwordProvider == null) 483 { 484 buffer.addElement(password); 485 } 486 else 487 { 488 final byte[] pwBytes; 489 try 490 { 491 pwBytes = passwordProvider.getPasswordBytes(); 492 } 493 catch (final LDAPException le) 494 { 495 Debug.debugException(le); 496 throw new LDAPRuntimeException(le); 497 } 498 499 final ASN1OctetString pw = new ASN1OctetString(CRED_TYPE_SIMPLE, pwBytes); 500 buffer.addElement(pw); 501 buffer.setZeroBufferOnClear(); 502 Arrays.fill(pwBytes, (byte) 0x00); 503 } 504 505 requestSequence.end(); 506 } 507 508 509 510 /** 511 * {@inheritDoc} 512 * Use of this method is only supported if the bind request was created with a 513 * static password. It is not allowed if the password will be obtained 514 * through a password provider. 515 * 516 * @throws LDAPSDKUsageException If this bind request was created with a 517 * password provider rather than a static 518 * password. 519 */ 520 @Override() 521 @NotNull() 522 public ASN1Element encodeProtocolOp() 523 throws LDAPSDKUsageException 524 { 525 if (password == null) 526 { 527 throw new LDAPSDKUsageException( 528 ERR_SIMPLE_BIND_ENCODE_PROTOCOL_OP_WITH_PROVIDER.get()); 529 } 530 531 return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_BIND_REQUEST, 532 new ASN1Integer(3), 533 bindDN, 534 password); 535 } 536 537 538 539 /** 540 * {@inheritDoc} 541 */ 542 @Override() 543 @NotNull() 544 protected BindResult process(@NotNull final LDAPConnection connection, 545 final int depth) 546 throws LDAPException 547 { 548 setReferralDepth(depth); 549 550 // See if a bind DN was provided without a password. If that is the case 551 // and this should not be allowed, then throw an exception. 552 if (password != null) 553 { 554 if ((bindDN.getValue().length > 0) && (password.getValue().length == 0) && 555 connection.getConnectionOptions().bindWithDNRequiresPassword()) 556 { 557 final LDAPException le = new LDAPException(ResultCode.PARAM_ERROR, 558 ERR_SIMPLE_BIND_DN_WITHOUT_PASSWORD.get()); 559 Debug.debugCodingError(le); 560 throw le; 561 } 562 } 563 564 565 if (connection.synchronousMode()) 566 { 567 return processSync(connection); 568 } 569 570 // Create the LDAP message. 571 messageID = connection.nextMessageID(); 572 final LDAPMessage message = new LDAPMessage(messageID, this, getControls()); 573 574 575 // Register with the connection reader to be notified of responses for the 576 // request that we've created. 577 connection.registerResponseAcceptor(messageID, this); 578 579 580 try 581 { 582 // Send the request to the server. 583 final long responseTimeout = getResponseTimeoutMillis(connection); 584 Debug.debugLDAPRequest(Level.INFO, this, messageID, connection); 585 586 final LDAPConnectionLogger logger = 587 connection.getConnectionOptions().getConnectionLogger(); 588 if (logger != null) 589 { 590 logger.logBindRequest(connection, messageID, this); 591 } 592 593 final long requestTime = System.nanoTime(); 594 connection.getConnectionStatistics().incrementNumBindRequests(); 595 connection.sendMessage(message, responseTimeout); 596 597 // Wait for and process the response. 598 final LDAPResponse response; 599 try 600 { 601 if (responseTimeout > 0) 602 { 603 response = responseQueue.poll(responseTimeout, TimeUnit.MILLISECONDS); 604 } 605 else 606 { 607 response = responseQueue.take(); 608 } 609 } 610 catch (final InterruptedException ie) 611 { 612 Debug.debugException(ie); 613 Thread.currentThread().interrupt(); 614 throw new LDAPException(ResultCode.LOCAL_ERROR, 615 ERR_BIND_INTERRUPTED.get(connection.getHostPort()), ie); 616 } 617 618 return handleResponse(connection, response, requestTime); 619 } 620 finally 621 { 622 connection.deregisterResponseAcceptor(messageID); 623 } 624 } 625 626 627 628 /** 629 * Processes this bind operation in synchronous mode, in which the same 630 * thread will send the request and read the response. 631 * 632 * @param connection The connection to use to communicate with the directory 633 * server. 634 * 635 * @return An LDAP result object that provides information about the result 636 * of the bind processing. 637 * 638 * @throws LDAPException If a problem occurs while sending the request or 639 * reading the response. 640 */ 641 @NotNull() 642 private BindResult processSync(@NotNull final LDAPConnection connection) 643 throws LDAPException 644 { 645 // Create the LDAP message. 646 messageID = connection.nextMessageID(); 647 final LDAPMessage message = 648 new LDAPMessage(messageID, this, getControls()); 649 650 651 // Send the request to the server. 652 final long requestTime = System.nanoTime(); 653 Debug.debugLDAPRequest(Level.INFO, this, messageID, connection); 654 655 final LDAPConnectionLogger logger = 656 connection.getConnectionOptions().getConnectionLogger(); 657 if (logger != null) 658 { 659 logger.logBindRequest(connection, messageID, this); 660 } 661 662 connection.getConnectionStatistics().incrementNumBindRequests(); 663 connection.sendMessage(message, getResponseTimeoutMillis(connection)); 664 665 while (true) 666 { 667 final LDAPResponse response = connection.readResponse(messageID); 668 if (response instanceof IntermediateResponse) 669 { 670 final IntermediateResponseListener listener = 671 getIntermediateResponseListener(); 672 if (listener != null) 673 { 674 listener.intermediateResponseReturned( 675 (IntermediateResponse) response); 676 } 677 } 678 else 679 { 680 return handleResponse(connection, response, requestTime); 681 } 682 } 683 } 684 685 686 687 /** 688 * Performs the necessary processing for handling a response. 689 * 690 * @param connection The connection used to read the response. 691 * @param response The response to be processed. 692 * @param requestTime The time the request was sent to the server. 693 * 694 * @return The bind result. 695 * 696 * @throws LDAPException If a problem occurs. 697 */ 698 @NotNull() 699 private BindResult handleResponse(@NotNull final LDAPConnection connection, 700 @Nullable final LDAPResponse response, 701 final long requestTime) 702 throws LDAPException 703 { 704 if (response == null) 705 { 706 final long waitTime = 707 StaticUtils.nanosToMillis(System.nanoTime() - requestTime); 708 throw new LDAPException(ResultCode.TIMEOUT, 709 ERR_SIMPLE_BIND_CLIENT_TIMEOUT.get(waitTime, messageID, 710 bindDN.stringValue(), connection.getHostPort())); 711 } 712 713 connection.getConnectionStatistics().incrementNumBindResponses( 714 System.nanoTime() - requestTime); 715 if (response instanceof ConnectionClosedResponse) 716 { 717 // The connection was closed while waiting for the response. 718 final ConnectionClosedResponse ccr = (ConnectionClosedResponse) response; 719 final String message = ccr.getMessage(); 720 if (message == null) 721 { 722 throw new LDAPException(ccr.getResultCode(), 723 ERR_CONN_CLOSED_WAITING_FOR_BIND_RESPONSE.get( 724 connection.getHostPort(), toString())); 725 } 726 else 727 { 728 throw new LDAPException(ccr.getResultCode(), 729 ERR_CONN_CLOSED_WAITING_FOR_BIND_RESPONSE_WITH_MESSAGE.get( 730 connection.getHostPort(), toString(), message)); 731 } 732 } 733 734 final BindResult bindResult = (BindResult) response; 735 return bindResult; 736 } 737 738 739 740 /** 741 * {@inheritDoc} 742 */ 743 @Override() 744 @NotNull() 745 public SimpleBindRequest getRebindRequest(@NotNull final String host, 746 final int port) 747 { 748 return new SimpleBindRequest(bindDN, password, passwordProvider, 749 getControls()); 750 } 751 752 753 754 /** 755 * {@inheritDoc} 756 */ 757 @InternalUseOnly() 758 @Override() 759 public void responseReceived(@NotNull final LDAPResponse response) 760 throws LDAPException 761 { 762 try 763 { 764 responseQueue.put(response); 765 } 766 catch (final Exception e) 767 { 768 Debug.debugException(e); 769 770 if (e instanceof InterruptedException) 771 { 772 Thread.currentThread().interrupt(); 773 } 774 775 throw new LDAPException(ResultCode.LOCAL_ERROR, 776 ERR_EXCEPTION_HANDLING_RESPONSE.get( 777 StaticUtils.getExceptionMessage(e)), 778 e); 779 } 780 } 781 782 783 784 /** 785 * {@inheritDoc} 786 */ 787 @Override() 788 @NotNull() 789 public String getBindType() 790 { 791 return "SIMPLE"; 792 } 793 794 795 796 /** 797 * {@inheritDoc} 798 */ 799 @Override() 800 public int getLastMessageID() 801 { 802 return messageID; 803 } 804 805 806 807 /** 808 * {@inheritDoc} 809 */ 810 @Override() 811 @NotNull() 812 public SimpleBindRequest duplicate() 813 { 814 return duplicate(getControls()); 815 } 816 817 818 819 /** 820 * {@inheritDoc} 821 */ 822 @Override() 823 @NotNull() 824 public SimpleBindRequest duplicate(@Nullable final Control[] controls) 825 { 826 final SimpleBindRequest bindRequest = 827 new SimpleBindRequest(bindDN, password, passwordProvider, controls); 828 bindRequest.setResponseTimeoutMillis(getResponseTimeoutMillis(null)); 829 bindRequest.setIntermediateResponseListener( 830 getIntermediateResponseListener()); 831 bindRequest.setReferralDepth(getReferralDepth()); 832 bindRequest.setReferralConnector(getReferralConnectorInternal()); 833 return bindRequest; 834 } 835 836 837 838 /** 839 * {@inheritDoc} 840 */ 841 @Override() 842 public void toString(@NotNull final StringBuilder buffer) 843 { 844 buffer.append("SimpleBindRequest(dn='"); 845 buffer.append(bindDN); 846 buffer.append('\''); 847 848 final Control[] controls = getControls(); 849 if (controls.length > 0) 850 { 851 buffer.append(", controls={"); 852 for (int i=0; i < controls.length; i++) 853 { 854 if (i > 0) 855 { 856 buffer.append(", "); 857 } 858 859 buffer.append(controls[i]); 860 } 861 buffer.append('}'); 862 } 863 864 buffer.append(')'); 865 } 866 867 868 869 /** 870 * {@inheritDoc} 871 */ 872 @Override() 873 public void toCode(@NotNull final List<String> lineList, 874 @NotNull final String requestID, 875 final int indentSpaces, final boolean includeProcessing) 876 { 877 // Create the request variable. 878 final ArrayList<ToCodeArgHelper> constructorArgs = new ArrayList<>(3); 879 constructorArgs.add(ToCodeArgHelper.createString(bindDN.stringValue(), 880 "Bind DN")); 881 constructorArgs.add(ToCodeArgHelper.createString("---redacted-password---", 882 "Bind Password")); 883 884 final Control[] controls = getControls(); 885 if (controls.length > 0) 886 { 887 constructorArgs.add(ToCodeArgHelper.createControlArray(controls, 888 "Bind Controls")); 889 } 890 891 ToCodeHelper.generateMethodCall(lineList, indentSpaces, "SimpleBindRequest", 892 requestID + "Request", "new SimpleBindRequest", constructorArgs); 893 894 895 // Add lines for processing the request and obtaining the result. 896 if (includeProcessing) 897 { 898 // Generate a string with the appropriate indent. 899 final StringBuilder buffer = new StringBuilder(); 900 for (int i=0; i < indentSpaces; i++) 901 { 902 buffer.append(' '); 903 } 904 final String indent = buffer.toString(); 905 906 lineList.add(""); 907 lineList.add(indent + "try"); 908 lineList.add(indent + '{'); 909 lineList.add(indent + " BindResult " + requestID + 910 "Result = connection.bind(" + requestID + "Request);"); 911 lineList.add(indent + " // The bind was processed successfully."); 912 lineList.add(indent + '}'); 913 lineList.add(indent + "catch (LDAPException e)"); 914 lineList.add(indent + '{'); 915 lineList.add(indent + " // The bind failed. Maybe the following will " + 916 "help explain why."); 917 lineList.add(indent + " // Note that the connection is now likely in " + 918 "an unauthenticated state."); 919 lineList.add(indent + " ResultCode resultCode = e.getResultCode();"); 920 lineList.add(indent + " String message = e.getMessage();"); 921 lineList.add(indent + " String matchedDN = e.getMatchedDN();"); 922 lineList.add(indent + " String[] referralURLs = e.getReferralURLs();"); 923 lineList.add(indent + " Control[] responseControls = " + 924 "e.getResponseControls();"); 925 lineList.add(indent + '}'); 926 } 927 } 928}