001/* 002 * Copyright 2016-2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2016-2019 Ping Identity Corporation 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.unboundidds.tools; 022 023 024 025import java.util.ArrayList; 026import java.util.Arrays; 027import java.util.List; 028import java.util.Map; 029 030import com.unboundid.asn1.ASN1OctetString; 031import com.unboundid.ldap.sdk.Attribute; 032import com.unboundid.ldap.sdk.Control; 033import com.unboundid.ldap.sdk.Entry; 034import com.unboundid.ldap.sdk.ExtendedResult; 035import com.unboundid.ldap.sdk.LDAPException; 036import com.unboundid.ldap.sdk.LDAPResult; 037import com.unboundid.ldap.sdk.OperationType; 038import com.unboundid.ldap.sdk.ResultCode; 039import com.unboundid.ldap.sdk.SearchResult; 040import com.unboundid.ldap.sdk.SearchResultEntry; 041import com.unboundid.ldap.sdk.SearchResultReference; 042import com.unboundid.ldap.sdk.controls.AuthorizationIdentityResponseControl; 043import com.unboundid.ldap.sdk.controls.ContentSyncDoneControl; 044import com.unboundid.ldap.sdk.controls.ContentSyncStateControl; 045import com.unboundid.ldap.sdk.controls.EntryChangeNotificationControl; 046import com.unboundid.ldap.sdk.controls.PasswordExpiredControl; 047import com.unboundid.ldap.sdk.controls.PasswordExpiringControl; 048import com.unboundid.ldap.sdk.controls.PersistentSearchChangeType; 049import com.unboundid.ldap.sdk.controls.PostReadResponseControl; 050import com.unboundid.ldap.sdk.controls.PreReadResponseControl; 051import com.unboundid.ldap.sdk.controls.ServerSideSortResponseControl; 052import com.unboundid.ldap.sdk.controls.SimplePagedResultsControl; 053import com.unboundid.ldap.sdk.controls.VirtualListViewResponseControl; 054import com.unboundid.ldap.sdk.extensions.AbortedTransactionExtendedResult; 055import com.unboundid.ldap.sdk.extensions.EndTransactionExtendedResult; 056import com.unboundid.ldap.sdk.extensions.NoticeOfDisconnectionExtendedResult; 057import com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedResult; 058import com.unboundid.ldap.sdk.extensions.StartTransactionExtendedResult; 059import com.unboundid.ldap.sdk.unboundidds.controls.AccountUsableResponseControl; 060import com.unboundid.ldap.sdk.unboundidds.controls.AssuredReplicationLocalLevel; 061import com.unboundid.ldap.sdk.unboundidds.controls. 062 AssuredReplicationRemoteLevel; 063import com.unboundid.ldap.sdk.unboundidds.controls. 064 AssuredReplicationServerResult; 065import com.unboundid.ldap.sdk.unboundidds.controls. 066 AssuredReplicationServerResultCode; 067import com.unboundid.ldap.sdk.unboundidds.controls. 068 AssuredReplicationResponseControl; 069import com.unboundid.ldap.sdk.unboundidds.controls.AuthenticationFailureReason; 070import com.unboundid.ldap.sdk.unboundidds.controls. 071 GetAuthorizationEntryResponseControl; 072import com.unboundid.ldap.sdk.unboundidds.controls. 073 GetBackendSetIDResponseControl; 074import com.unboundid.ldap.sdk.unboundidds.controls. 075 GetPasswordPolicyStateIssuesResponseControl; 076import com.unboundid.ldap.sdk.unboundidds.controls.GetServerIDResponseControl; 077import com.unboundid.ldap.sdk.unboundidds.controls. 078 GetUserResourceLimitsResponseControl; 079import com.unboundid.ldap.sdk.unboundidds.controls. 080 IntermediateClientResponseControl; 081import com.unboundid.ldap.sdk.unboundidds.controls. 082 IntermediateClientResponseValue; 083import com.unboundid.ldap.sdk.unboundidds.controls.JoinedEntry; 084import com.unboundid.ldap.sdk.unboundidds.controls.JoinResultControl; 085import com.unboundid.ldap.sdk.unboundidds.controls. 086 MatchingEntryCountResponseControl; 087import com.unboundid.ldap.sdk.unboundidds.controls.PasswordPolicyErrorType; 088import com.unboundid.ldap.sdk.unboundidds.controls. 089 PasswordPolicyResponseControl; 090import com.unboundid.ldap.sdk.unboundidds.controls.PasswordPolicyWarningType; 091import com.unboundid.ldap.sdk.unboundidds.controls. 092 PasswordQualityRequirementValidationResult; 093import com.unboundid.ldap.sdk.unboundidds.controls. 094 PasswordValidationDetailsResponseControl; 095import com.unboundid.ldap.sdk.unboundidds.controls.SoftDeleteResponseControl; 096import com.unboundid.ldap.sdk.unboundidds.controls. 097 TransactionSettingsResponseControl; 098import com.unboundid.ldap.sdk.unboundidds.controls.UniquenessResponseControl; 099import com.unboundid.ldap.sdk.unboundidds.extensions.MultiUpdateChangesApplied; 100import com.unboundid.ldap.sdk.unboundidds.extensions.MultiUpdateExtendedResult; 101import com.unboundid.ldap.sdk.unboundidds.extensions. 102 PasswordPolicyStateAccountUsabilityError; 103import com.unboundid.ldap.sdk.unboundidds.extensions. 104 PasswordPolicyStateAccountUsabilityNotice; 105import com.unboundid.ldap.sdk.unboundidds.extensions. 106 PasswordPolicyStateAccountUsabilityWarning; 107import com.unboundid.ldap.sdk.unboundidds.extensions.PasswordQualityRequirement; 108import com.unboundid.util.Debug; 109import com.unboundid.util.ObjectPair; 110import com.unboundid.util.StaticUtils; 111import com.unboundid.util.ThreadSafety; 112import com.unboundid.util.ThreadSafetyLevel; 113 114import static com.unboundid.ldap.sdk.unboundidds.tools.ToolMessages.*; 115 116 117 118/** 119 * This class provides a set of utility methods for formatting operation 120 * results. 121 * <BR> 122 * <BLOCKQUOTE> 123 * <B>NOTE:</B> This class, and other classes within the 124 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 125 * supported for use against Ping Identity, UnboundID, and 126 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 127 * for proprietary functionality or for external specifications that are not 128 * considered stable or mature enough to be guaranteed to work in an 129 * interoperable way with other types of LDAP servers. 130 * </BLOCKQUOTE> 131 */ 132@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 133public final class ResultUtils 134{ 135 /** 136 * Ensures that this utility class can't be instantiated. 137 */ 138 private ResultUtils() 139 { 140 // No implementation required. 141 } 142 143 144 145 /** 146 * Retrieves a list of strings that comprise a formatted representation of the 147 * provided result. 148 * 149 * @param result The result to be formatted. 150 * @param comment Indicates whether to prefix each line with an octothorpe 151 * to indicate that it is a comment. 152 * @param indent The number of spaces to indent each line. 153 * @param maxWidth The maximum length of each line in characters, including 154 * the comment prefix and indent. 155 * 156 * @return A list of strings that comprise a formatted representation of the 157 * provided result. 158 */ 159 public static List<String> formatResult(final LDAPResult result, 160 final boolean comment, 161 final int indent, final int maxWidth) 162 { 163 final ArrayList<String> lines = new ArrayList<>(10); 164 formatResult(lines, result, comment, false, indent, maxWidth); 165 return lines; 166 } 167 168 169 170 /** 171 * Retrieves a list of strings that comprise a formatted representation of the 172 * result encapsulated by the provided exception. 173 * 174 * @param ldapException The exception to use to obtain the result to format. 175 * @param comment Indicates whether to prefix each line with an 176 * octothorpe to indicate that it is a comment. 177 * @param indent The number of spaces to indent each line. 178 * @param maxWidth The maximum length of each line in characters, 179 * including the comment prefix and indent. 180 * 181 * @return A list of strings that comprise a formatted representation of the 182 * result encapsulated by the provided exception. 183 */ 184 public static List<String> formatResult(final LDAPException ldapException, 185 final boolean comment, 186 final int indent, final int maxWidth) 187 { 188 return formatResult(ldapException.toLDAPResult(), comment, indent, 189 maxWidth); 190 } 191 192 193 194 /** 195 * Adds a multi-line string representation of the provided result to the 196 * given list. 197 * 198 * @param lines The list to which the lines should be added. 199 * @param result The result to be formatted. 200 * @param comment Indicates whether to prefix each line with an octothorpe 201 * to indicate that it is a comment. 202 * @param inTxn Indicates whether the operation is part of an active 203 * transaction. 204 * @param indent The number of spaces to indent each line. 205 * @param maxWidth The maximum length of each line in characters, including 206 * the comment prefix and indent. 207 */ 208 public static void formatResult(final List<String> lines, 209 final LDAPResult result, 210 final boolean comment, final boolean inTxn, 211 final int indent, final int maxWidth) 212 { 213 formatResult(lines, result, inTxn, createPrefix(comment, indent), maxWidth); 214 } 215 216 217 218 /** 219 * Adds a multi-line string representation of the provided result to the 220 * given list. 221 * 222 * @param lines The list to which the lines should be added. 223 * @param result The result to be formatted. 224 * @param inTxn Indicates whether the operation is part of an active 225 * transaction. 226 * @param prefix The prefix to use for each line. 227 * @param maxWidth The maximum length of each line in characters, including 228 * the comment prefix and indent. 229 */ 230 private static void formatResult(final List<String> lines, 231 final LDAPResult result, final boolean inTxn, 232 final String prefix, final int maxWidth) 233 { 234 // Format the result code. If it's a success result but the operation was 235 // part of a transaction, then indicate that no change has actually been 236 // made yet. 237 final ResultCode resultCode = result.getResultCode(); 238 wrap(lines, INFO_RESULT_UTILS_RESULT_CODE.get(String.valueOf(resultCode)), 239 prefix, maxWidth); 240 if (inTxn && (resultCode == ResultCode.SUCCESS)) 241 { 242 wrap(lines, INFO_RESULT_UTILS_SUCCESS_WITH_TXN.get(), prefix, maxWidth); 243 } 244 245 246 // Format the diagnostic message, if there is one. 247 final String diagnosticMessage = result.getDiagnosticMessage(); 248 if (diagnosticMessage != null) 249 { 250 wrap(lines, INFO_RESULT_UTILS_DIAGNOSTIC_MESSAGE.get(diagnosticMessage), 251 prefix, maxWidth); 252 } 253 254 255 // Format the matched DN, if there is one. 256 final String matchedDN = result.getMatchedDN(); 257 if (matchedDN != null) 258 { 259 wrap(lines, INFO_RESULT_UTILS_MATCHED_DN.get(matchedDN), prefix, 260 maxWidth); 261 } 262 263 264 // If there are any referral URLs, then display them. 265 final String[] referralURLs = result.getReferralURLs(); 266 if (referralURLs != null) 267 { 268 for (final String referralURL : referralURLs) 269 { 270 wrap(lines, INFO_RESULT_UTILS_REFERRAL_URL.get(referralURL), prefix, 271 maxWidth); 272 } 273 } 274 275 276 if (result instanceof SearchResult) 277 { 278 final SearchResult searchResult = (SearchResult) result; 279 280 // We'll always display the search entry count if we know it. 281 final int numEntries = searchResult.getEntryCount(); 282 if (numEntries >= 0) 283 { 284 wrap(lines, INFO_RESULT_UTILS_NUM_SEARCH_ENTRIES.get(numEntries), 285 prefix, maxWidth); 286 } 287 288 // We'll only display the search reference count if it's greater than 289 // zero. 290 final int numReferences = searchResult.getReferenceCount(); 291 if (numReferences > 0) 292 { 293 wrap(lines, INFO_RESULT_UTILS_NUM_SEARCH_REFERENCES.get(numReferences), 294 prefix, maxWidth); 295 } 296 } 297 else if (result instanceof StartTransactionExtendedResult) 298 { 299 final StartTransactionExtendedResult startTxnResult = 300 (StartTransactionExtendedResult) result; 301 final ASN1OctetString txnID = startTxnResult.getTransactionID(); 302 if (txnID != null) 303 { 304 if (StaticUtils.isPrintableString(txnID.getValue())) 305 { 306 wrap(lines, 307 INFO_RESULT_UTILS_START_TXN_RESULT_TXN_ID.get( 308 txnID.stringValue()), 309 prefix, maxWidth); 310 } 311 else 312 { 313 wrap(lines, 314 INFO_RESULT_UTILS_START_TXN_RESULT_TXN_ID.get( 315 "0x" + StaticUtils.toHex(txnID.getValue())), 316 prefix, maxWidth); 317 } 318 } 319 } 320 else if (result instanceof EndTransactionExtendedResult) 321 { 322 final EndTransactionExtendedResult endTxnResult = 323 (EndTransactionExtendedResult) result; 324 final int failedOpMessageID = endTxnResult.getFailedOpMessageID(); 325 if (failedOpMessageID > 0) 326 { 327 wrap(lines, 328 INFO_RESULT_UTILS_END_TXN_RESULT_FAILED_MSG_ID.get( 329 failedOpMessageID), 330 prefix, maxWidth); 331 } 332 333 final Map<Integer,Control[]> controls = 334 endTxnResult.getOperationResponseControls(); 335 if (controls != null) 336 { 337 for (final Map.Entry<Integer,Control[]> e : controls.entrySet()) 338 { 339 for (final Control c : e.getValue()) 340 { 341 wrap(lines, 342 INFO_RESULT_UTILS_END_TXN_RESULT_OP_CONTROL.get(e.getKey()), 343 prefix, maxWidth); 344 formatResponseControl(lines, c, prefix + " ", maxWidth); 345 } 346 } 347 } 348 } 349 else if (result instanceof MultiUpdateExtendedResult) 350 { 351 final MultiUpdateExtendedResult multiUpdateResult = 352 (MultiUpdateExtendedResult) result; 353 354 final MultiUpdateChangesApplied changesApplied = 355 multiUpdateResult.getChangesApplied(); 356 if (changesApplied != null) 357 { 358 wrap(lines, 359 INFO_RESULT_UTILS_MULTI_UPDATE_CHANGES_APPLIED.get( 360 changesApplied.name()), 361 prefix, maxWidth); 362 } 363 364 final List<ObjectPair<OperationType,LDAPResult>> multiUpdateResults = 365 multiUpdateResult.getResults(); 366 if (multiUpdateResults != null) 367 { 368 for (final ObjectPair<OperationType,LDAPResult> p : multiUpdateResults) 369 { 370 wrap(lines, 371 INFO_RESULT_UTILS_MULTI_UPDATE_RESULT_HEADER.get( 372 p.getFirst().name()), 373 prefix, maxWidth); 374 formatResult(lines, p.getSecond(), false, prefix + " ", maxWidth); 375 } 376 } 377 } 378 else if (result instanceof PasswordModifyExtendedResult) 379 { 380 final PasswordModifyExtendedResult passwordModifyResult = 381 (PasswordModifyExtendedResult) result; 382 383 final String generatedPassword = 384 passwordModifyResult.getGeneratedPassword(); 385 if (generatedPassword != null) 386 { 387 wrap(lines, 388 INFO_RESULT_UTILS_PASSWORD_MODIFY_RESULT_GENERATED_PW.get( 389 generatedPassword), 390 prefix, maxWidth); 391 } 392 } 393 else if (result instanceof ExtendedResult) 394 { 395 final ExtendedResult extendedResult = (ExtendedResult) result; 396 final String oid = ((ExtendedResult) result).getOID(); 397 if (oid != null) 398 { 399 wrap(lines, INFO_RESULT_UTILS_RESPONSE_EXTOP_OID.get(oid), prefix, 400 maxWidth); 401 } 402 403 final ASN1OctetString value = extendedResult.getValue(); 404 if ((value != null) && (value.getValueLength() > 0)) 405 { 406 wrap(lines, INFO_RESULT_UTILS_RESPONSE_EXTOP_RAW_VALUE_HEADER.get(), 407 prefix, maxWidth); 408 409 // We'll ignore the maximum width for this portion of the output. 410 for (final String line : 411 StaticUtils.stringToLines( 412 StaticUtils.toHexPlusASCII(value.getValue(), 0))) 413 { 414 lines.add(prefix + " " + line); 415 } 416 } 417 } 418 419 420 // If there are any controls, then display them. We'll interpret any 421 // controls that we can, but will fall back to a general display for any 422 // that we don't recognize or can't parse. 423 final Control[] controls = result.getResponseControls(); 424 if (controls != null) 425 { 426 for (final Control c : controls) 427 { 428 formatResponseControl(lines, c, prefix, maxWidth); 429 } 430 } 431 } 432 433 434 435 /** 436 * Updates the provided list with an LDIF representation of the provided 437 * search result entry to the given list, preceded by comments about any 438 * controls that may be included with the entry. 439 * 440 * @param lines The list to which the formatted representation will be 441 * added. 442 * @param entry The entry to be formatted. 443 * @param maxWidth The maximum length of each line in characters, including 444 * any comment prefix and indent. 445 */ 446 public static void formatSearchResultEntry(final List<String> lines, 447 final SearchResultEntry entry, 448 final int maxWidth) 449 { 450 for (final Control c : entry.getControls()) 451 { 452 formatResponseControl(lines, c, true, 0, maxWidth); 453 } 454 455 lines.addAll(Arrays.asList(entry.toLDIF(maxWidth))); 456 } 457 458 459 460 /** 461 * Updates the provided with with a string representation of the provided 462 * search result reference. The information will be written as LDIF 463 * comments, and will include any referral URLs contained in the reference, as 464 * well as information about any associated controls. 465 * 466 * @param lines The list to which the formatted representation will be 467 * added. 468 * @param reference The search result reference to be formatted. 469 * @param maxWidth The maximum length of each line in characters, including 470 * any comment prefix and indent. 471 */ 472 public static void formatSearchResultReference(final List<String> lines, 473 final SearchResultReference reference, 474 final int maxWidth) 475 { 476 wrap(lines, INFO_RESULT_UTILS_SEARCH_REFERENCE_HEADER.get(), "# ", 477 maxWidth); 478 for (final String url : reference.getReferralURLs()) 479 { 480 wrap(lines, INFO_RESULT_UTILS_REFERRAL_URL.get(url), "# ", maxWidth); 481 } 482 483 for (final Control c : reference.getControls()) 484 { 485 formatResponseControl(lines, c, "# ", maxWidth); 486 } 487 } 488 489 490 491 /** 492 * Adds a multi-line string representation of the provided unsolicited 493 * notification to the given list. 494 * 495 * @param lines The list to which the lines should be added. 496 * @param notification The unsolicited notification to be formatted. 497 * @param comment Indicates whether to prefix each line with an 498 * octothorpe to indicate that it is a comment. 499 * @param indent The number of spaces to indent each line. 500 * @param maxWidth The maximum length of each line in characters, 501 * including the comment prefix and indent. 502 */ 503 public static void formatUnsolicitedNotification(final List<String> lines, 504 final ExtendedResult notification, 505 final boolean comment, final int indent, 506 final int maxWidth) 507 { 508 final String prefix = createPrefix(comment, indent); 509 final String indentPrefix = prefix + " "; 510 511 boolean includeRawValue = true; 512 final String oid = notification.getOID(); 513 if (oid != null) 514 { 515 if (oid.equals(NoticeOfDisconnectionExtendedResult. 516 NOTICE_OF_DISCONNECTION_RESULT_OID)) 517 { 518 wrap(lines, INFO_RESULT_UTILS_NOTICE_OF_DISCONNECTION_HEADER.get(), 519 prefix, maxWidth); 520 wrap(lines, INFO_RESULT_UTILS_RESPONSE_EXTOP_OID.get(oid), 521 indentPrefix, maxWidth); 522 } 523 else if (oid.equals(AbortedTransactionExtendedResult. 524 ABORTED_TRANSACTION_RESULT_OID)) 525 { 526 wrap(lines, INFO_RESULT_UTILS_ABORTED_TXN_HEADER.get(), prefix, 527 maxWidth); 528 wrap(lines, INFO_RESULT_UTILS_RESPONSE_EXTOP_OID.get(oid), 529 indentPrefix, maxWidth); 530 531 try 532 { 533 final AbortedTransactionExtendedResult r = 534 new AbortedTransactionExtendedResult(notification); 535 536 final String txnID; 537 if (StaticUtils.isPrintableString(r.getTransactionID().getValue())) 538 { 539 txnID = r.getTransactionID().stringValue(); 540 } 541 else 542 { 543 txnID = "0x" + StaticUtils.toHex(r.getTransactionID().getValue()); 544 } 545 wrap(lines, INFO_RESULT_UTILS_TXN_ID_HEADER.get(txnID), indentPrefix, 546 maxWidth); 547 includeRawValue = false; 548 } 549 catch (final Exception e) 550 { 551 Debug.debugException(e); 552 } 553 } 554 else 555 { 556 wrap(lines, INFO_RESULT_UTILS_UNSOLICITED_NOTIFICATION_HEADER.get(), 557 prefix, maxWidth); 558 wrap(lines, INFO_RESULT_UTILS_RESPONSE_EXTOP_OID.get(oid), 559 indentPrefix, maxWidth); 560 } 561 } 562 else 563 { 564 wrap(lines, INFO_RESULT_UTILS_UNSOLICITED_NOTIFICATION_HEADER.get(), 565 prefix, maxWidth); 566 } 567 568 569 wrap(lines, 570 INFO_RESULT_UTILS_RESULT_CODE.get( 571 String.valueOf(notification.getResultCode())), 572 indentPrefix, maxWidth); 573 574 final String diagnosticMessage = notification.getDiagnosticMessage(); 575 if (diagnosticMessage != null) 576 { 577 wrap(lines, 578 INFO_RESULT_UTILS_DIAGNOSTIC_MESSAGE.get(diagnosticMessage), 579 indentPrefix, maxWidth); 580 } 581 582 final String matchedDN = notification.getMatchedDN(); 583 if (matchedDN != null) 584 { 585 wrap(lines, INFO_RESULT_UTILS_MATCHED_DN.get(matchedDN), indentPrefix, 586 maxWidth); 587 } 588 589 final String[] referralURLs = notification.getReferralURLs(); 590 if (referralURLs != null) 591 { 592 for (final String referralURL : referralURLs) 593 { 594 wrap(lines, INFO_RESULT_UTILS_REFERRAL_URL.get(referralURL), 595 indentPrefix, maxWidth); 596 } 597 } 598 599 if (includeRawValue) 600 { 601 final ASN1OctetString value = notification.getValue(); 602 if ((value != null) && (value.getValueLength() > 0)) 603 { 604 wrap(lines, INFO_RESULT_UTILS_RESPONSE_EXTOP_RAW_VALUE_HEADER.get(), 605 indentPrefix, maxWidth); 606 607 // We'll ignore the maximum width for this portion of the output. 608 for (final String line : 609 StaticUtils.stringToLines( 610 StaticUtils.toHexPlusASCII(value.getValue(), 0))) 611 { 612 lines.add(prefix + " " + line); 613 } 614 } 615 } 616 617 618 // If there are any controls, then display them. We'll interpret any 619 // controls that we can, but will fall back to a general display for any 620 // that we don't recognize or can't parse. 621 final Control[] controls = notification.getResponseControls(); 622 if (controls != null) 623 { 624 for (final Control c : controls) 625 { 626 formatResponseControl(lines, c, comment, indent+5, maxWidth); 627 } 628 } 629 } 630 631 632 633 /** 634 * Adds a multi-line string representation of the provided result to the 635 * given list. 636 * 637 * @param lines The list to which the lines should be added. 638 * @param c The control to be formatted. 639 * @param comment Indicates whether to prefix each line with an octothorpe 640 * to indicate that it is a comment. 641 * @param indent The number of spaces to indent each line. 642 * @param maxWidth The maximum length of each line in characters, including 643 * the comment prefix and indent. 644 */ 645 public static void formatResponseControl(final List<String> lines, 646 final Control c, 647 final boolean comment, 648 final int indent, final int maxWidth) 649 { 650 // Generate a prefix that will be used for every line. 651 final StringBuilder buffer = new StringBuilder(indent + 2); 652 if (comment) 653 { 654 buffer.append("# "); 655 } 656 for (int i=0; i < indent; i++) 657 { 658 buffer.append(' '); 659 } 660 final String prefix = buffer.toString(); 661 662 663 formatResponseControl(lines, c, prefix, maxWidth); 664 } 665 666 667 668 /** 669 * Adds a multi-line string representation of the provided control to the 670 * given list. 671 * 672 * @param lines The list to which the lines should be added. 673 * @param c The control to be formatted. 674 * @param prefix The prefix to use for each line. 675 * @param maxWidth The maximum length of each line in characters, including 676 * the comment prefix and indent. 677 */ 678 private static void formatResponseControl(final List<String> lines, 679 final Control c, 680 final String prefix, 681 final int maxWidth) 682 { 683 final String oid = c.getOID(); 684 if (oid.equals(AuthorizationIdentityResponseControl. 685 AUTHORIZATION_IDENTITY_RESPONSE_OID)) 686 { 687 addAuthorizationIdentityResponseControl(lines, c, prefix, maxWidth); 688 } 689 else if (oid.equals(ContentSyncDoneControl.SYNC_DONE_OID)) 690 { 691 addContentSyncDoneControl(lines, c, prefix, maxWidth); 692 } 693 else if (oid.equals(ContentSyncStateControl.SYNC_STATE_OID)) 694 { 695 addContentSyncStateControl(lines, c, prefix, maxWidth); 696 } 697 else if (oid.equals(EntryChangeNotificationControl. 698 ENTRY_CHANGE_NOTIFICATION_OID)) 699 { 700 addEntryChangeNotificationControl(lines, c, prefix, maxWidth); 701 } 702 else if (oid.equals(PasswordExpiredControl.PASSWORD_EXPIRED_OID)) 703 { 704 addPasswordExpiredControl(lines, c, prefix, maxWidth); 705 } 706 else if (oid.equals(PasswordExpiringControl.PASSWORD_EXPIRING_OID)) 707 { 708 addPasswordExpiringControl(lines, c, prefix, maxWidth); 709 } 710 else if (oid.equals(PostReadResponseControl.POST_READ_RESPONSE_OID)) 711 { 712 addPostReadResponseControl(lines, c, prefix, maxWidth); 713 } 714 else if (oid.equals(PreReadResponseControl.PRE_READ_RESPONSE_OID)) 715 { 716 addPreReadResponseControl(lines, c, prefix, maxWidth); 717 } 718 else if (oid.equals(ServerSideSortResponseControl. 719 SERVER_SIDE_SORT_RESPONSE_OID)) 720 { 721 addServerSideSortResponseControl(lines, c, prefix, maxWidth); 722 } 723 else if (oid.equals(SimplePagedResultsControl.PAGED_RESULTS_OID)) 724 { 725 addSimplePagedResultsControl(lines, c, prefix, maxWidth); 726 } 727 else if (oid.equals(VirtualListViewResponseControl. 728 VIRTUAL_LIST_VIEW_RESPONSE_OID)) 729 { 730 addVirtualListViewResponseControl(lines, c, prefix, maxWidth); 731 } 732 else if (oid.equals(AccountUsableResponseControl. 733 ACCOUNT_USABLE_RESPONSE_OID)) 734 { 735 addAccountUsableResponseControl(lines, c, prefix, maxWidth); 736 } 737 else if (oid.equals(AssuredReplicationResponseControl. 738 ASSURED_REPLICATION_RESPONSE_OID)) 739 { 740 addAssuredReplicationResponseControl(lines, c, prefix, maxWidth); 741 } 742 else if (oid.equals(GetAuthorizationEntryResponseControl. 743 GET_AUTHORIZATION_ENTRY_RESPONSE_OID)) 744 { 745 addGetAuthorizationEntryResponseControl(lines, c, prefix, maxWidth); 746 } 747 else if (oid.equals(GetBackendSetIDResponseControl. 748 GET_BACKEND_SET_ID_RESPONSE_OID)) 749 { 750 addGetBackendSetIDResponseControl(lines, c, prefix, maxWidth); 751 } 752 else if (oid.equals(GetPasswordPolicyStateIssuesResponseControl. 753 GET_PASSWORD_POLICY_STATE_ISSUES_RESPONSE_OID)) 754 { 755 addGetPasswordPolicyStateIssuesResponseControl(lines, c, prefix, 756 maxWidth); 757 } 758 else if (oid.equals(GetServerIDResponseControl.GET_SERVER_ID_RESPONSE_OID)) 759 { 760 addGetServerIDResponseControl(lines, c, prefix, maxWidth); 761 } 762 else if (oid.equals(GetUserResourceLimitsResponseControl. 763 GET_USER_RESOURCE_LIMITS_RESPONSE_OID)) 764 { 765 addGetUserResourceLimitsResponseControl(lines, c, prefix, maxWidth); 766 } 767 else if (oid.equals(IntermediateClientResponseControl. 768 INTERMEDIATE_CLIENT_RESPONSE_OID)) 769 { 770 addIntermediateClientResponseControl(lines, c, prefix, maxWidth); 771 } 772 else if (oid.equals(JoinResultControl.JOIN_RESULT_OID)) 773 { 774 addJoinResultControl(lines, c, prefix, maxWidth); 775 } 776 else if (oid.equals(MatchingEntryCountResponseControl. 777 MATCHING_ENTRY_COUNT_RESPONSE_OID)) 778 { 779 addMatchingEntryCountResponseControl(lines, c, prefix, maxWidth); 780 } 781 else if (oid.equals(PasswordPolicyResponseControl. 782 PASSWORD_POLICY_RESPONSE_OID)) 783 { 784 addPasswordPolicyResponseControl(lines, c, prefix, maxWidth); 785 } 786 else if (oid.equals(PasswordValidationDetailsResponseControl. 787 PASSWORD_VALIDATION_DETAILS_RESPONSE_OID)) 788 { 789 addPasswordValidationDetailsResponseControl(lines, c, prefix, maxWidth); 790 } 791 else if (oid.equals(SoftDeleteResponseControl.SOFT_DELETE_RESPONSE_OID)) 792 { 793 addSoftDeleteResponseControl(lines, c, prefix, maxWidth); 794 } 795 else if (oid.equals(TransactionSettingsResponseControl. 796 TRANSACTION_SETTINGS_RESPONSE_OID)) 797 { 798 addTransactionSettingsResponseControl(lines, c, prefix, maxWidth); 799 } 800 else if (oid.equals(UniquenessResponseControl.UNIQUENESS_RESPONSE_OID)) 801 { 802 addUniquenessResponseControl(lines, c, prefix, maxWidth); 803 } 804 else 805 { 806 addGenericResponseControl(lines, c, prefix, maxWidth); 807 } 808 } 809 810 811 812 /** 813 * Adds a multi-line string representation of the provided control, which will 814 * be treated as a generic control, to the given list. 815 * 816 * @param lines The list to which the lines should be added. 817 * @param c The control to be formatted. 818 * @param prefix The prefix to use for each line. 819 * @param maxWidth The maximum length of each line in characters, including 820 * the comment prefix and indent. 821 */ 822 private static void addGenericResponseControl(final List<String> lines, 823 final Control c, 824 final String prefix, 825 final int maxWidth) 826 { 827 wrap(lines, INFO_RESULT_UTILS_GENERIC_RESPONSE_CONTROL_HEADER.get(), 828 prefix, maxWidth); 829 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 830 prefix + " ", maxWidth); 831 wrap(lines, 832 INFO_RESULT_UTILS_RESPONSE_CONTROL_IS_CRITICAL.get(c.isCritical()), 833 prefix + " ", maxWidth); 834 835 final ASN1OctetString value = c.getValue(); 836 if ((value != null) && (value.getValue().length > 0)) 837 { 838 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_RAW_VALUE_HEADER.get(), 839 prefix + " ", maxWidth); 840 841 // We'll ignore the maximum width for this portion of the output. 842 for (final String line : 843 StaticUtils.stringToLines( 844 StaticUtils.toHexPlusASCII(value.getValue(), 0))) 845 { 846 lines.add(prefix + " " + line); 847 } 848 } 849 } 850 851 852 853 /** 854 * Adds a multi-line string representation of the provided control, which is 855 * expected to be an authorization identity response control, to the given 856 * list. 857 * 858 * @param lines The list to which the lines should be added. 859 * @param c The control to be formatted. 860 * @param prefix The prefix to use for each line. 861 * @param maxWidth The maximum length of each line in characters, including 862 * the comment prefix and indent. 863 */ 864 private static void addAuthorizationIdentityResponseControl( 865 final List<String> lines, final Control c, 866 final String prefix, final int maxWidth) 867 { 868 final AuthorizationIdentityResponseControl decoded; 869 try 870 { 871 decoded = new AuthorizationIdentityResponseControl(c.getOID(), 872 c.isCritical(), c.getValue()); 873 } 874 catch (final Exception e) 875 { 876 Debug.debugException(e); 877 addGenericResponseControl(lines, c, prefix, maxWidth); 878 return; 879 } 880 881 wrap(lines, INFO_RESULT_UTILS_AUTHZ_ID_RESPONSE_HEADER.get(), prefix, 882 maxWidth); 883 884 final String indentPrefix = prefix + " "; 885 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 886 indentPrefix, maxWidth); 887 wrap(lines, 888 INFO_RESULT_UTILS_AUTHZ_ID_RESPONSE_ID.get( 889 decoded.getAuthorizationID()), 890 indentPrefix, maxWidth); 891 } 892 893 894 895 /** 896 * Adds a multi-line string representation of the provided control, which is 897 * expected to be a content sync done control, to the given list. 898 * 899 * @param lines The list to which the lines should be added. 900 * @param c The control to be formatted. 901 * @param prefix The prefix to use for each line. 902 * @param maxWidth The maximum length of each line in characters, including 903 * the comment prefix and indent. 904 */ 905 private static void addContentSyncDoneControl( 906 final List<String> lines, final Control c, 907 final String prefix, final int maxWidth) 908 { 909 final ContentSyncDoneControl decoded; 910 try 911 { 912 decoded = new ContentSyncDoneControl(c.getOID(), c.isCritical(), 913 c.getValue()); 914 } 915 catch (final Exception e) 916 { 917 Debug.debugException(e); 918 addGenericResponseControl(lines, c, prefix, maxWidth); 919 return; 920 } 921 922 wrap(lines, INFO_RESULT_UTILS_CONTENT_SYNC_DONE_RESPONSE_HEADER.get(), 923 prefix, maxWidth); 924 final String indentPrefix = prefix + " "; 925 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 926 indentPrefix, maxWidth); 927 wrap(lines, 928 INFO_RESULT_UTILS_CONTENT_SYNC_DONE_REFRESH_DELETES.get( 929 decoded.refreshDeletes()), 930 indentPrefix, maxWidth); 931 932 final ASN1OctetString cookie = decoded.getCookie(); 933 if (cookie != null) 934 { 935 wrap(lines, INFO_RESULT_UTILS_CONTENT_SYNC_DONE_COOKIE_HEADER.get(), 936 indentPrefix, maxWidth); 937 938 // We'll ignore the maximum width for this portion of the output. 939 for (final String line : 940 StaticUtils.stringToLines( 941 StaticUtils.toHexPlusASCII(cookie.getValue(), 0))) 942 { 943 lines.add(indentPrefix + " " + line); 944 } 945 } 946 } 947 948 949 950 /** 951 * Adds a multi-line string representation of the provided control, which is 952 * expected to be a content sync state control, to the given list. 953 * 954 * @param lines The list to which the lines should be added. 955 * @param c The control to be formatted. 956 * @param prefix The prefix to use for each line. 957 * @param maxWidth The maximum length of each line in characters, including 958 * the comment prefix and indent. 959 */ 960 private static void addContentSyncStateControl( 961 final List<String> lines, final Control c, 962 final String prefix, final int maxWidth) 963 { 964 final ContentSyncStateControl decoded; 965 try 966 { 967 decoded = new ContentSyncStateControl(c.getOID(), c.isCritical(), 968 c.getValue()); 969 } 970 catch (final Exception e) 971 { 972 Debug.debugException(e); 973 addGenericResponseControl(lines, c, prefix, maxWidth); 974 return; 975 } 976 977 wrap(lines, INFO_RESULT_UTILS_CONTENT_SYNC_STATE_RESPONSE_HEADER.get(), 978 prefix, maxWidth); 979 final String indentPrefix = prefix + " "; 980 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 981 indentPrefix, maxWidth); 982 wrap(lines, 983 INFO_RESULT_UTILS_CONTENT_SYNC_STATE_ENTRY_UUID.get( 984 decoded.getEntryUUID()), 985 indentPrefix, maxWidth); 986 wrap(lines, 987 INFO_RESULT_UTILS_CONTENT_SYNC_STATE_NAME.get( 988 decoded.getState().name()), 989 indentPrefix, maxWidth); 990 991 final ASN1OctetString cookie = decoded.getCookie(); 992 if (cookie != null) 993 { 994 wrap(lines, INFO_RESULT_UTILS_CONTENT_SYNC_STATE_COOKIE_HEADER.get(), 995 indentPrefix, maxWidth); 996 997 // We'll ignore the maximum width for this portion of the output. 998 for (final String line : 999 StaticUtils.stringToLines( 1000 StaticUtils.toHexPlusASCII(cookie.getValue(), 0))) 1001 { 1002 lines.add(indentPrefix + " " + line); 1003 } 1004 } 1005 } 1006 1007 1008 1009 /** 1010 * Adds a multi-line string representation of the provided control, which is 1011 * expected to be an entry change notification control, to the given list. 1012 * 1013 * @param lines The list to which the lines should be added. 1014 * @param c The control to be formatted. 1015 * @param prefix The prefix to use for each line. 1016 * @param maxWidth The maximum length of each line in characters, including 1017 * the comment prefix and indent. 1018 */ 1019 private static void addEntryChangeNotificationControl( 1020 final List<String> lines, final Control c, 1021 final String prefix, final int maxWidth) 1022 { 1023 final EntryChangeNotificationControl decoded; 1024 try 1025 { 1026 decoded = new EntryChangeNotificationControl(c.getOID(), c.isCritical(), 1027 c.getValue()); 1028 } 1029 catch (final Exception e) 1030 { 1031 Debug.debugException(e); 1032 addGenericResponseControl(lines, c, prefix, maxWidth); 1033 return; 1034 } 1035 1036 wrap(lines, INFO_RESULT_UTILS_ECN_HEADER.get(), prefix, maxWidth); 1037 1038 final String indentPrefix = prefix + " "; 1039 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1040 indentPrefix, maxWidth); 1041 1042 final PersistentSearchChangeType changeType = decoded.getChangeType(); 1043 if (changeType != null) 1044 { 1045 wrap(lines, INFO_RESULT_UTILS_ECN_CHANGE_TYPE.get(changeType.getName()), 1046 indentPrefix, maxWidth); 1047 } 1048 1049 final long changeNumber = decoded.getChangeNumber(); 1050 if (changeNumber >= 0L) 1051 { 1052 wrap(lines, INFO_RESULT_UTILS_ECN_CHANGE_NUMBER.get(changeNumber), 1053 indentPrefix, maxWidth); 1054 } 1055 1056 final String previousDN = decoded.getPreviousDN(); 1057 if (previousDN != null) 1058 { 1059 wrap(lines, INFO_RESULT_UTILS_ECN_PREVIOUS_DN.get(previousDN), 1060 indentPrefix, maxWidth); 1061 } 1062 } 1063 1064 1065 1066 /** 1067 * Adds a multi-line string representation of the provided control, which is 1068 * expected to be a password expired control, to the given list. 1069 * 1070 * @param lines The list to which the lines should be added. 1071 * @param c The control to be formatted. 1072 * @param prefix The prefix to use for each line. 1073 * @param maxWidth The maximum length of each line in characters, including 1074 * the comment prefix and indent. 1075 */ 1076 private static void addPasswordExpiredControl(final List<String> lines, 1077 final Control c, 1078 final String prefix, 1079 final int maxWidth) 1080 { 1081 final PasswordExpiredControl decoded; 1082 try 1083 { 1084 decoded = new PasswordExpiredControl(c.getOID(), c.isCritical(), 1085 c.getValue()); 1086 } 1087 catch (final Exception e) 1088 { 1089 Debug.debugException(e); 1090 addGenericResponseControl(lines, c, prefix, maxWidth); 1091 return; 1092 } 1093 1094 wrap(lines, INFO_RESULT_UTILS_PASSWORD_EXPIRED_HEADER.get(), prefix, 1095 maxWidth); 1096 1097 final String indentPrefix = prefix + " "; 1098 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(decoded.getOID()), 1099 indentPrefix, maxWidth); 1100 } 1101 1102 1103 1104 /** 1105 * Adds a multi-line string representation of the provided control, which is 1106 * expected to be a password expiring control, to the given list. 1107 * 1108 * @param lines The list to which the lines should be added. 1109 * @param c The control to be formatted. 1110 * @param prefix The prefix to use for each line. 1111 * @param maxWidth The maximum length of each line in characters, including 1112 * the comment prefix and indent. 1113 */ 1114 private static void addPasswordExpiringControl(final List<String> lines, 1115 final Control c, 1116 final String prefix, 1117 final int maxWidth) 1118 { 1119 final PasswordExpiringControl decoded; 1120 try 1121 { 1122 decoded = new PasswordExpiringControl(c.getOID(), c.isCritical(), 1123 c.getValue()); 1124 } 1125 catch (final Exception e) 1126 { 1127 Debug.debugException(e); 1128 addGenericResponseControl(lines, c, prefix, maxWidth); 1129 return; 1130 } 1131 1132 wrap(lines, INFO_RESULT_UTILS_PASSWORD_EXPIRING_HEADER.get(), prefix, 1133 maxWidth); 1134 1135 final String indentPrefix = prefix + " "; 1136 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1137 indentPrefix, maxWidth); 1138 1139 final int secondsUntilExpiration = decoded.getSecondsUntilExpiration(); 1140 if (secondsUntilExpiration >= 0) 1141 { 1142 wrap(lines, 1143 INFO_RESULT_UTILS_PASSWORD_EXPIRING_SECONDS_UNTIL_EXPIRATION.get( 1144 secondsUntilExpiration), 1145 indentPrefix, maxWidth); 1146 } 1147 } 1148 1149 1150 1151 /** 1152 * Adds a multi-line string representation of the provided control, which is 1153 * expected to be a post-read response control, to the given list. 1154 * 1155 * @param lines The list to which the lines should be added. 1156 * @param c The control to be formatted. 1157 * @param prefix The prefix to use for each line. 1158 * @param maxWidth The maximum length of each line in characters, including 1159 * the comment prefix and indent. 1160 */ 1161 private static void addPostReadResponseControl( 1162 final List<String> lines, final Control c, 1163 final String prefix, final int maxWidth) 1164 { 1165 final PostReadResponseControl decoded; 1166 try 1167 { 1168 decoded = new PostReadResponseControl(c.getOID(), c.isCritical(), 1169 c.getValue()); 1170 } 1171 catch (final Exception e) 1172 { 1173 Debug.debugException(e); 1174 addGenericResponseControl(lines, c, prefix, maxWidth); 1175 return; 1176 } 1177 1178 wrap(lines, INFO_RESULT_UTILS_POST_READ_HEADER.get(), prefix, maxWidth); 1179 1180 final String indentPrefix = prefix + " "; 1181 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1182 indentPrefix, maxWidth); 1183 wrap(lines, INFO_RESULT_UTILS_POST_READ_ENTRY_HEADER.get(c.getOID()), 1184 indentPrefix, maxWidth); 1185 addLDIF(lines, decoded.getEntry(), true, indentPrefix + " ", maxWidth); 1186 } 1187 1188 1189 1190 /** 1191 * Adds a multi-line string representation of the provided control, which is 1192 * expected to be a pre-read response control, to the given list. 1193 * 1194 * @param lines The list to which the lines should be added. 1195 * @param c The control to be formatted. 1196 * @param prefix The prefix to use for each line. 1197 * @param maxWidth The maximum length of each line in characters, including 1198 * the comment prefix and indent. 1199 */ 1200 private static void addPreReadResponseControl( 1201 final List<String> lines, final Control c, 1202 final String prefix, final int maxWidth) 1203 { 1204 final PreReadResponseControl decoded; 1205 try 1206 { 1207 decoded = new PreReadResponseControl(c.getOID(), c.isCritical(), 1208 c.getValue()); 1209 } 1210 catch (final Exception e) 1211 { 1212 Debug.debugException(e); 1213 addGenericResponseControl(lines, c, prefix, maxWidth); 1214 return; 1215 } 1216 1217 wrap(lines, INFO_RESULT_UTILS_PRE_READ_HEADER.get(), prefix, maxWidth); 1218 1219 final String indentPrefix = prefix + " "; 1220 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1221 indentPrefix, maxWidth); 1222 wrap(lines, INFO_RESULT_UTILS_PRE_READ_ENTRY_HEADER.get(c.getOID()), 1223 indentPrefix, maxWidth); 1224 addLDIF(lines, decoded.getEntry(), true, indentPrefix + " ", maxWidth); 1225 } 1226 1227 1228 1229 /** 1230 * Adds a multi-line string representation of the provided control, which is 1231 * expected to be a server-side sort response control, to the given list. 1232 * 1233 * @param lines The list to which the lines should be added. 1234 * @param c The control to be formatted. 1235 * @param prefix The prefix to use for each line. 1236 * @param maxWidth The maximum length of each line in characters, including 1237 * the comment prefix and indent. 1238 */ 1239 private static void addServerSideSortResponseControl( 1240 final List<String> lines, final Control c, 1241 final String prefix, final int maxWidth) 1242 { 1243 final ServerSideSortResponseControl decoded; 1244 try 1245 { 1246 decoded = new ServerSideSortResponseControl(c.getOID(), c.isCritical(), 1247 c.getValue()); 1248 } 1249 catch (final Exception e) 1250 { 1251 Debug.debugException(e); 1252 addGenericResponseControl(lines, c, prefix, maxWidth); 1253 return; 1254 } 1255 1256 wrap(lines, INFO_RESULT_UTILS_SORT_HEADER.get(), prefix, maxWidth); 1257 1258 final String indentPrefix = prefix + " "; 1259 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1260 indentPrefix, maxWidth); 1261 1262 final ResultCode resultCode = decoded.getResultCode(); 1263 if (resultCode != null) 1264 { 1265 wrap(lines, 1266 INFO_RESULT_UTILS_SORT_RESULT_CODE.get(String.valueOf(resultCode)), 1267 indentPrefix, maxWidth); 1268 } 1269 1270 final String attributeName = decoded.getAttributeName(); 1271 if (attributeName != null) 1272 { 1273 wrap(lines, INFO_RESULT_UTILS_SORT_ATTRIBUTE_NAME.get(attributeName), 1274 indentPrefix, maxWidth); 1275 } 1276 } 1277 1278 1279 1280 /** 1281 * Adds a multi-line string representation of the provided control, which is 1282 * expected to be a simple paged results control, to the given list. 1283 * 1284 * @param lines The list to which the lines should be added. 1285 * @param c The control to be formatted. 1286 * @param prefix The prefix to use for each line. 1287 * @param maxWidth The maximum length of each line in characters, including 1288 * the comment prefix and indent. 1289 */ 1290 private static void addSimplePagedResultsControl( 1291 final List<String> lines, final Control c, 1292 final String prefix, final int maxWidth) 1293 { 1294 final SimplePagedResultsControl decoded; 1295 try 1296 { 1297 decoded = new SimplePagedResultsControl(c.getOID(), c.isCritical(), 1298 c.getValue()); 1299 } 1300 catch (final Exception e) 1301 { 1302 Debug.debugException(e); 1303 addGenericResponseControl(lines, c, prefix, maxWidth); 1304 return; 1305 } 1306 1307 wrap(lines, INFO_RESULT_UTILS_PAGED_RESULTS_HEADER.get(), prefix, maxWidth); 1308 1309 final String indentPrefix = prefix + " "; 1310 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1311 indentPrefix, maxWidth); 1312 1313 final int estimatedCount = decoded.getSize(); 1314 if (estimatedCount >= 0) 1315 { 1316 wrap(lines, INFO_RESULT_UTILS_PAGED_RESULTS_COUNT.get(estimatedCount), 1317 indentPrefix, maxWidth); 1318 } 1319 1320 final ASN1OctetString cookie = decoded.getCookie(); 1321 if (cookie != null) 1322 { 1323 wrap(lines, INFO_RESULT_UTILS_PAGED_RESULTS_COOKIE_HEADER.get(), 1324 indentPrefix, maxWidth); 1325 1326 // We'll ignore the maximum width for this portion of the output. 1327 for (final String line : 1328 StaticUtils.stringToLines( 1329 StaticUtils.toHexPlusASCII(cookie.getValue(), 0))) 1330 { 1331 lines.add(indentPrefix + " " + line); 1332 } 1333 } 1334 } 1335 1336 1337 1338 /** 1339 * Adds a multi-line string representation of the provided control, which is 1340 * expected to be a virtual list view response control, to the given list. 1341 * 1342 * @param lines The list to which the lines should be added. 1343 * @param c The control to be formatted. 1344 * @param prefix The prefix to use for each line. 1345 * @param maxWidth The maximum length of each line in characters, including 1346 * the comment prefix and indent. 1347 */ 1348 private static void addVirtualListViewResponseControl( 1349 final List<String> lines, final Control c, 1350 final String prefix, final int maxWidth) 1351 { 1352 final VirtualListViewResponseControl decoded; 1353 try 1354 { 1355 decoded = new VirtualListViewResponseControl(c.getOID(), c.isCritical(), 1356 c.getValue()); 1357 } 1358 catch (final Exception e) 1359 { 1360 Debug.debugException(e); 1361 addGenericResponseControl(lines, c, prefix, maxWidth); 1362 return; 1363 } 1364 1365 wrap(lines, INFO_RESULT_UTILS_VLV_HEADER.get(), prefix, maxWidth); 1366 1367 final String indentPrefix = prefix + " "; 1368 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1369 indentPrefix, maxWidth); 1370 1371 final ResultCode resultCode = decoded.getResultCode(); 1372 if (resultCode != null) 1373 { 1374 wrap(lines, 1375 INFO_RESULT_UTILS_VLV_RESULT_CODE.get(String.valueOf(resultCode)), 1376 indentPrefix, maxWidth); 1377 } 1378 1379 final int contentCount = decoded.getContentCount(); 1380 if (contentCount >= 0) 1381 { 1382 wrap(lines, INFO_RESULT_UTILS_VLV_CONTENT_COUNT.get(contentCount), 1383 indentPrefix, maxWidth); 1384 } 1385 1386 final int targetPosition = decoded.getTargetPosition(); 1387 if (targetPosition >= 0) 1388 { 1389 wrap(lines, INFO_RESULT_UTILS_VLV_TARGET_POSITION.get(targetPosition), 1390 indentPrefix, maxWidth); 1391 } 1392 1393 final ASN1OctetString contextID = decoded.getContextID(); 1394 if (contextID != null) 1395 { 1396 wrap(lines, INFO_RESULT_UTILS_VLV_CONTEXT_ID_HEADER.get(), 1397 indentPrefix, maxWidth); 1398 1399 // We'll ignore the maximum width for this portion of the output. 1400 for (final String line : 1401 StaticUtils.stringToLines( 1402 StaticUtils.toHexPlusASCII(contextID.getValue(), 0))) 1403 { 1404 lines.add(indentPrefix + " " + line); 1405 } 1406 } 1407 } 1408 1409 1410 1411 /** 1412 * Adds a multi-line string representation of the provided control, which is 1413 * expected to be an account usable response control, to the given list. 1414 * 1415 * @param lines The list to which the lines should be added. 1416 * @param c The control to be formatted. 1417 * @param prefix The prefix to use for each line. 1418 * @param maxWidth The maximum length of each line in characters, including 1419 * the comment prefix and indent. 1420 */ 1421 private static void addAccountUsableResponseControl( 1422 final List<String> lines, final Control c, 1423 final String prefix, final int maxWidth) 1424 { 1425 final AccountUsableResponseControl decoded; 1426 try 1427 { 1428 decoded = new AccountUsableResponseControl(c.getOID(), c.isCritical(), 1429 c.getValue()); 1430 } 1431 catch (final Exception e) 1432 { 1433 Debug.debugException(e); 1434 addGenericResponseControl(lines, c, prefix, maxWidth); 1435 return; 1436 } 1437 1438 wrap(lines, INFO_RESULT_UTILS_ACCOUNT_USABLE_HEADER.get(), prefix, 1439 maxWidth); 1440 1441 final String indentPrefix = prefix + " "; 1442 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1443 indentPrefix, maxWidth); 1444 wrap(lines, 1445 INFO_RESULT_UTILS_ACCOUNT_USABLE_IS_USABLE.get(decoded.isUsable()), 1446 indentPrefix, maxWidth); 1447 1448 final List<String> unusableReasons = decoded.getUnusableReasons(); 1449 if ((unusableReasons != null) && (! unusableReasons.isEmpty())) 1450 { 1451 wrap(lines, 1452 INFO_RESULT_UTILS_ACCOUNT_USABLE_UNUSABLE_REASONS_HEADER.get(), 1453 indentPrefix, maxWidth); 1454 for (final String reason : unusableReasons) 1455 { 1456 wrap(lines, reason, indentPrefix + " ", maxWidth); 1457 } 1458 } 1459 1460 wrap(lines, 1461 INFO_RESULT_UTILS_ACCOUNT_USABLE_PW_EXPIRED.get( 1462 decoded.passwordIsExpired()), 1463 indentPrefix, maxWidth); 1464 wrap(lines, 1465 INFO_RESULT_UTILS_ACCOUNT_USABLE_MUST_CHANGE_PW.get( 1466 decoded.mustChangePassword()), 1467 indentPrefix, maxWidth); 1468 wrap(lines, 1469 INFO_RESULT_UTILS_ACCOUNT_USABLE_IS_INACTIVE.get(decoded.isInactive()), 1470 indentPrefix, maxWidth); 1471 1472 final int remainingGraceLogins = decoded.getRemainingGraceLogins(); 1473 if (remainingGraceLogins >= 0) 1474 { 1475 wrap(lines, 1476 INFO_RESULT_UTILS_ACCOUNT_USABLE_REMAINING_GRACE.get( 1477 remainingGraceLogins), 1478 indentPrefix, maxWidth); 1479 } 1480 1481 final int secondsUntilExpiration = decoded.getSecondsUntilExpiration(); 1482 if (secondsUntilExpiration >= 0) 1483 { 1484 wrap(lines, 1485 INFO_RESULT_UTILS_ACCOUNT_USABLE_SECONDS_UNTIL_EXPIRATION.get( 1486 secondsUntilExpiration), 1487 indentPrefix, maxWidth); 1488 } 1489 1490 final int secondsUntilUnlock = decoded.getSecondsUntilUnlock(); 1491 if (secondsUntilUnlock >= 0) 1492 { 1493 wrap(lines, 1494 INFO_RESULT_UTILS_ACCOUNT_USABLE_SECONDS_UNTIL_UNLOCK.get( 1495 secondsUntilUnlock), 1496 indentPrefix, maxWidth); 1497 } 1498 } 1499 1500 1501 1502 /** 1503 * Adds a multi-line string representation of the provided control, which is 1504 * expected to be an assured replication response control, to the given list. 1505 * 1506 * @param lines The list to which the lines should be added. 1507 * @param c The control to be formatted. 1508 * @param prefix The prefix to use for each line. 1509 * @param maxWidth The maximum length of each line in characters, including 1510 * the comment prefix and indent. 1511 */ 1512 private static void addAssuredReplicationResponseControl( 1513 final List<String> lines, final Control c, 1514 final String prefix, final int maxWidth) 1515 { 1516 final AssuredReplicationResponseControl decoded; 1517 try 1518 { 1519 decoded = new AssuredReplicationResponseControl(c.getOID(), 1520 c.isCritical(), c.getValue()); 1521 } 1522 catch (final Exception e) 1523 { 1524 Debug.debugException(e); 1525 addGenericResponseControl(lines, c, prefix, maxWidth); 1526 return; 1527 } 1528 1529 wrap(lines, INFO_RESULT_UTILS_ASSURED_REPL_HEADER.get(), prefix, maxWidth); 1530 1531 final String indentPrefix = prefix + " "; 1532 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1533 indentPrefix, maxWidth); 1534 1535 final String csn = decoded.getCSN(); 1536 if (csn != null) 1537 { 1538 wrap(lines, INFO_RESULT_UTILS_ASSURED_REPL_CSN.get(csn), indentPrefix, 1539 maxWidth); 1540 } 1541 1542 final AssuredReplicationLocalLevel localLevel = decoded.getLocalLevel(); 1543 if (localLevel != null) 1544 { 1545 wrap(lines, 1546 INFO_RESULT_UTILS_ASSURED_REPL_LOCAL_LEVEL.get(localLevel.name()), 1547 indentPrefix, maxWidth); 1548 } 1549 1550 wrap(lines, 1551 INFO_RESULT_UTILS_ASSURED_REPL_LOCAL_SATISFIED.get( 1552 decoded.localAssuranceSatisfied()), 1553 indentPrefix, maxWidth); 1554 1555 final String localMessage = decoded.getLocalAssuranceMessage(); 1556 if (localMessage != null) 1557 { 1558 wrap(lines, 1559 INFO_RESULT_UTILS_ASSURED_REPL_LOCAL_MESSAGE.get(localMessage), 1560 indentPrefix, maxWidth); 1561 } 1562 1563 final AssuredReplicationRemoteLevel remoteLevel = decoded.getRemoteLevel(); 1564 if (remoteLevel != null) 1565 { 1566 wrap(lines, 1567 INFO_RESULT_UTILS_ASSURED_REPL_REMOTE_LEVEL.get(remoteLevel.name()), 1568 indentPrefix, maxWidth); 1569 } 1570 1571 wrap(lines, 1572 INFO_RESULT_UTILS_ASSURED_REPL_REMOTE_SATISFIED.get( 1573 decoded.remoteAssuranceSatisfied()), 1574 indentPrefix, maxWidth); 1575 1576 final String remoteMessage = decoded.getRemoteAssuranceMessage(); 1577 if (remoteMessage != null) 1578 { 1579 wrap(lines, 1580 INFO_RESULT_UTILS_ASSURED_REPL_REMOTE_MESSAGE.get(remoteMessage), 1581 indentPrefix, maxWidth); 1582 } 1583 1584 final List<AssuredReplicationServerResult> serverResults = 1585 decoded.getServerResults(); 1586 if (serverResults != null) 1587 { 1588 for (final AssuredReplicationServerResult r : serverResults) 1589 { 1590 wrap(lines, 1591 INFO_RESULT_UTILS_ASSURED_REPL_SERVER_RESULT_HEADER.get(), 1592 indentPrefix, maxWidth); 1593 1594 final AssuredReplicationServerResultCode rc = r.getResultCode(); 1595 if (rc != null) 1596 { 1597 wrap(lines, 1598 INFO_RESULT_UTILS_ASSURED_REPL_SERVER_RESULT_CODE.get(rc.name()), 1599 indentPrefix + " ", maxWidth); 1600 } 1601 1602 final Short replicationServerID = r.getReplicationServerID(); 1603 if (replicationServerID != null) 1604 { 1605 wrap(lines, 1606 INFO_RESULT_UTILS_ASSURED_REPL_SERVER_RESULT_REPL_SERVER_ID.get( 1607 replicationServerID), 1608 indentPrefix + " ", maxWidth); 1609 } 1610 1611 final Short replicaID = r.getReplicaID(); 1612 if (replicaID != null) 1613 { 1614 wrap(lines, 1615 INFO_RESULT_UTILS_ASSURED_REPL_SERVER_RESULT_REPL_ID.get( 1616 replicaID), 1617 indentPrefix + " ", maxWidth); 1618 } 1619 } 1620 } 1621 } 1622 1623 1624 1625 /** 1626 * Adds a multi-line string representation of the provided control, which is 1627 * expected to be a get authorization entry response control, to the given 1628 * list. 1629 * 1630 * @param lines The list to which the lines should be added. 1631 * @param c The control to be formatted. 1632 * @param prefix The prefix to use for each line. 1633 * @param maxWidth The maximum length of each line in characters, including 1634 * the comment prefix and indent. 1635 */ 1636 private static void addGetAuthorizationEntryResponseControl( 1637 final List<String> lines, final Control c, 1638 final String prefix, final int maxWidth) 1639 { 1640 final GetAuthorizationEntryResponseControl decoded; 1641 try 1642 { 1643 decoded = new GetAuthorizationEntryResponseControl(c.getOID(), 1644 c.isCritical(), c.getValue()); 1645 } 1646 catch (final Exception e) 1647 { 1648 Debug.debugException(e); 1649 addGenericResponseControl(lines, c, prefix, maxWidth); 1650 return; 1651 } 1652 1653 wrap(lines, INFO_RESULT_UTILS_GET_AUTHZ_ENTRY_HEADER.get(), prefix, 1654 maxWidth); 1655 1656 final String indentPrefix = prefix + " "; 1657 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1658 indentPrefix, maxWidth); 1659 wrap(lines, 1660 INFO_RESULT_UTILS_GET_AUTHZ_ENTRY_IS_AUTHENTICATED.get( 1661 decoded.isAuthenticated()), 1662 indentPrefix, maxWidth); 1663 1664 if (! decoded.isAuthenticated()) 1665 { 1666 return; 1667 } 1668 1669 wrap(lines, 1670 INFO_RESULT_UTILS_GET_AUTHZ_ENTRY_IDS_MATCH.get( 1671 decoded.identitiesMatch()), 1672 indentPrefix, maxWidth); 1673 1674 final String authNID = decoded.getAuthNID(); 1675 if (authNID != null) 1676 { 1677 wrap(lines, INFO_RESULT_UTILS_GET_AUTHZ_ENTRY_AUTHN_ID.get(authNID), 1678 indentPrefix, maxWidth); 1679 } 1680 1681 final Entry authNEntry = decoded.getAuthNEntry(); 1682 if (authNEntry != null) 1683 { 1684 wrap(lines, INFO_RESULT_UTILS_GET_AUTHZ_ENTRY_AUTHN_ENTRY_HEADER.get(), 1685 indentPrefix, maxWidth); 1686 addLDIF(lines, authNEntry, true, indentPrefix + " ", maxWidth); 1687 } 1688 1689 if (decoded.identitiesMatch()) 1690 { 1691 return; 1692 } 1693 1694 final String authZID = decoded.getAuthZID(); 1695 if (authZID != null) 1696 { 1697 wrap(lines, INFO_RESULT_UTILS_GET_AUTHZ_ENTRY_AUTHZ_ID.get(authZID), 1698 indentPrefix, maxWidth); 1699 } 1700 1701 final Entry authZEntry = decoded.getAuthZEntry(); 1702 if (authZEntry != null) 1703 { 1704 wrap(lines, INFO_RESULT_UTILS_GET_AUTHZ_ENTRY_AUTHZ_ENTRY_HEADER.get(), 1705 indentPrefix, maxWidth); 1706 addLDIF(lines, authZEntry, true, indentPrefix + " ", maxWidth); 1707 } 1708 } 1709 1710 1711 1712 /** 1713 * Adds a multi-line string representation of the provided control, which is 1714 * expected to be a get backend set ID response control, to the given list. 1715 * 1716 * @param lines The list to which the lines should be added. 1717 * @param c The control to be formatted. 1718 * @param prefix The prefix to use for each line. 1719 * @param maxWidth The maximum length of each line in characters, including 1720 * the comment prefix and indent. 1721 */ 1722 private static void addGetBackendSetIDResponseControl( 1723 final List<String> lines, final Control c, 1724 final String prefix, final int maxWidth) 1725 { 1726 final GetBackendSetIDResponseControl decoded; 1727 try 1728 { 1729 decoded = new GetBackendSetIDResponseControl(c.getOID(), c.isCritical(), 1730 c.getValue()); 1731 } 1732 catch (final Exception e) 1733 { 1734 Debug.debugException(e); 1735 addGenericResponseControl(lines, c, prefix, maxWidth); 1736 return; 1737 } 1738 1739 wrap(lines, INFO_RESULT_UTILS_GET_BACKEND_SET_ID_HEADER.get(), prefix, 1740 maxWidth); 1741 1742 final String indentPrefix = prefix + " "; 1743 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1744 indentPrefix, maxWidth); 1745 wrap(lines, 1746 INFO_RESULT_UTILS_GET_BACKEND_SET_ID_EB_RP_ID.get( 1747 decoded.getEntryBalancingRequestProcessorID()), 1748 indentPrefix, maxWidth); 1749 1750 for (final String id : decoded.getBackendSetIDs()) 1751 { 1752 wrap(lines, INFO_RESULT_UTILS_GET_BACKEND_SET_ID.get(id), indentPrefix, 1753 maxWidth); 1754 } 1755 } 1756 1757 1758 1759 /** 1760 * Adds a multi-line string representation of the provided control, which is 1761 * expected to be a get password policy state issues response control, to the 1762 * given list. 1763 * 1764 * @param lines The list to which the lines should be added. 1765 * @param c The control to be formatted. 1766 * @param prefix The prefix to use for each line. 1767 * @param maxWidth The maximum length of each line in characters, including 1768 * the comment prefix and indent. 1769 */ 1770 private static void addGetPasswordPolicyStateIssuesResponseControl( 1771 final List<String> lines, final Control c, 1772 final String prefix, final int maxWidth) 1773 { 1774 final GetPasswordPolicyStateIssuesResponseControl decoded; 1775 try 1776 { 1777 decoded = new GetPasswordPolicyStateIssuesResponseControl(c.getOID(), 1778 c.isCritical(), c.getValue()); 1779 } 1780 catch (final Exception e) 1781 { 1782 Debug.debugException(e); 1783 addGenericResponseControl(lines, c, prefix, maxWidth); 1784 return; 1785 } 1786 1787 wrap(lines, INFO_RESULT_UTILS_GET_PW_STATE_ISSUES_HEADER.get(), prefix, 1788 maxWidth); 1789 1790 final String indentPrefix = prefix + " "; 1791 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1792 indentPrefix, maxWidth); 1793 1794 final String doubleIndentPrefix = indentPrefix + " "; 1795 final AuthenticationFailureReason authFailureReason = 1796 decoded.getAuthenticationFailureReason(); 1797 if (authFailureReason != null) 1798 { 1799 wrap(lines, 1800 INFO_RESULT_UTILS_GET_PW_STATE_ISSUES_FAILURE_REASON_HEADER.get(), 1801 indentPrefix, maxWidth); 1802 wrap(lines, 1803 INFO_RESULT_UTILS_GET_PW_STATE_ISSUES_FAILURE_TYPE.get( 1804 authFailureReason.getName()), 1805 doubleIndentPrefix, maxWidth); 1806 1807 final String message = authFailureReason.getMessage(); 1808 if (message != null) 1809 { 1810 wrap(lines, 1811 INFO_RESULT_UTILS_GET_PW_STATE_ISSUES_FAILURE_MESSAGE.get(message), 1812 doubleIndentPrefix, maxWidth); 1813 } 1814 } 1815 1816 final List<PasswordPolicyStateAccountUsabilityError> errors = 1817 decoded.getErrors(); 1818 if (errors != null) 1819 { 1820 for (final PasswordPolicyStateAccountUsabilityError e : errors) 1821 { 1822 wrap(lines, INFO_RESULT_UTILS_GET_PW_STATE_ISSUES_ERROR_HEADER.get(), 1823 indentPrefix, maxWidth); 1824 wrap(lines, 1825 INFO_RESULT_UTILS_GET_PW_STATE_ISSUES_ERROR_NAME.get(e.getName()), 1826 doubleIndentPrefix, maxWidth); 1827 1828 final String message = e.getMessage(); 1829 if (message != null) 1830 { 1831 wrap(lines, 1832 INFO_RESULT_UTILS_GET_PW_STATE_ISSUES_ERROR_MESSAGE.get(message), 1833 doubleIndentPrefix, maxWidth); 1834 } 1835 } 1836 } 1837 1838 final List<PasswordPolicyStateAccountUsabilityWarning> warnings = 1839 decoded.getWarnings(); 1840 if (warnings != null) 1841 { 1842 for (final PasswordPolicyStateAccountUsabilityWarning w : warnings) 1843 { 1844 wrap(lines, INFO_RESULT_UTILS_GET_PW_STATE_ISSUES_WARNING_HEADER.get(), 1845 indentPrefix, maxWidth); 1846 wrap(lines, 1847 INFO_RESULT_UTILS_GET_PW_STATE_ISSUES_WARNING_NAME.get( 1848 w.getName()), 1849 doubleIndentPrefix, maxWidth); 1850 1851 final String message = w.getMessage(); 1852 if (message != null) 1853 { 1854 wrap(lines, 1855 INFO_RESULT_UTILS_GET_PW_STATE_ISSUES_WARNING_MESSAGE.get( 1856 message), 1857 doubleIndentPrefix, maxWidth); 1858 } 1859 } 1860 } 1861 1862 final List<PasswordPolicyStateAccountUsabilityNotice> notices = 1863 decoded.getNotices(); 1864 if (notices != null) 1865 { 1866 for (final PasswordPolicyStateAccountUsabilityNotice n : notices) 1867 { 1868 wrap(lines, INFO_RESULT_UTILS_GET_PW_STATE_ISSUES_NOTICE_HEADER.get(), 1869 indentPrefix, maxWidth); 1870 wrap(lines, 1871 INFO_RESULT_UTILS_GET_PW_STATE_ISSUES_NOTICE_NAME.get(n.getName()), 1872 doubleIndentPrefix, maxWidth); 1873 1874 final String message = n.getMessage(); 1875 if (message != null) 1876 { 1877 wrap(lines, 1878 INFO_RESULT_UTILS_GET_PW_STATE_ISSUES_NOTICE_MESSAGE.get( 1879 message), 1880 doubleIndentPrefix, maxWidth); 1881 } 1882 } 1883 } 1884 } 1885 1886 1887 1888 /** 1889 * Adds a multi-line string representation of the provided control, which is 1890 * expected to be a get server ID response control, to the given list. 1891 * 1892 * @param lines The list to which the lines should be added. 1893 * @param c The control to be formatted. 1894 * @param prefix The prefix to use for each line. 1895 * @param maxWidth The maximum length of each line in characters, including 1896 * the comment prefix and indent. 1897 */ 1898 private static void addGetServerIDResponseControl( 1899 final List<String> lines, final Control c, 1900 final String prefix, final int maxWidth) 1901 { 1902 final GetServerIDResponseControl decoded; 1903 try 1904 { 1905 decoded = new GetServerIDResponseControl(c.getOID(), c.isCritical(), 1906 c.getValue()); 1907 } 1908 catch (final Exception e) 1909 { 1910 Debug.debugException(e); 1911 addGenericResponseControl(lines, c, prefix, maxWidth); 1912 return; 1913 } 1914 1915 1916 wrap(lines, INFO_RESULT_UTILS_GET_SERVER_ID_HEADER.get(), prefix, 1917 maxWidth); 1918 1919 final String indentPrefix = prefix + " "; 1920 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1921 indentPrefix, maxWidth); 1922 wrap(lines, INFO_RESULT_UTILS_GET_SERVER_ID.get(decoded.getServerID()), 1923 indentPrefix, maxWidth); 1924 } 1925 1926 1927 1928 /** 1929 * Adds a multi-line string representation of the provided control, which is 1930 * expected to be a get user resource limits response control, to the given 1931 * list. 1932 * 1933 * @param lines The list to which the lines should be added. 1934 * @param c The control to be formatted. 1935 * @param prefix The prefix to use for each line. 1936 * @param maxWidth The maximum length of each line in characters, including 1937 * the comment prefix and indent. 1938 */ 1939 private static void addGetUserResourceLimitsResponseControl( 1940 final List<String> lines, final Control c, 1941 final String prefix, final int maxWidth) 1942 { 1943 final GetUserResourceLimitsResponseControl decoded; 1944 try 1945 { 1946 decoded = new GetUserResourceLimitsResponseControl(c.getOID(), 1947 c.isCritical(), c.getValue()); 1948 } 1949 catch (final Exception e) 1950 { 1951 Debug.debugException(e); 1952 addGenericResponseControl(lines, c, prefix, maxWidth); 1953 return; 1954 } 1955 1956 wrap(lines, INFO_RESULT_UTILS_GET_USER_RLIM_HEADER.get(), prefix, 1957 maxWidth); 1958 1959 final String indentPrefix = prefix + " "; 1960 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 1961 indentPrefix, maxWidth); 1962 1963 final Long sizeLimit = decoded.getSizeLimit(); 1964 if (sizeLimit != null) 1965 { 1966 final String value; 1967 if (sizeLimit > 0L) 1968 { 1969 value = String.valueOf(sizeLimit); 1970 } 1971 else 1972 { 1973 value = INFO_RESULT_UTILS_GET_USER_RLIM_VALUE_UNLIMITED.get(); 1974 } 1975 1976 wrap(lines, INFO_RESULT_UTILS_GET_USER_RLIM_SIZE_LIMIT.get(value), 1977 indentPrefix, maxWidth); 1978 } 1979 1980 final Long timeLimit = decoded.getTimeLimitSeconds(); 1981 if (timeLimit != null) 1982 { 1983 final String value; 1984 if (timeLimit > 0L) 1985 { 1986 value = timeLimit + " " + 1987 INFO_RESULT_UTILS_GET_USER_RLIM_UNIT_SECONDS.get(); 1988 } 1989 else 1990 { 1991 value = INFO_RESULT_UTILS_GET_USER_RLIM_VALUE_UNLIMITED.get(); 1992 } 1993 1994 wrap(lines, INFO_RESULT_UTILS_GET_USER_RLIM_TIME_LIMIT.get(value), 1995 indentPrefix, maxWidth); 1996 } 1997 1998 final Long idleTimeLimit = decoded.getIdleTimeLimitSeconds(); 1999 if (idleTimeLimit != null) 2000 { 2001 final String value; 2002 if (idleTimeLimit > 0L) 2003 { 2004 value = idleTimeLimit + " " + 2005 INFO_RESULT_UTILS_GET_USER_RLIM_UNIT_SECONDS.get(); 2006 } 2007 else 2008 { 2009 value = INFO_RESULT_UTILS_GET_USER_RLIM_VALUE_UNLIMITED.get(); 2010 } 2011 2012 wrap(lines, INFO_RESULT_UTILS_GET_USER_RLIM_IDLE_TIME_LIMIT.get(value), 2013 indentPrefix, maxWidth); 2014 } 2015 2016 final Long lookthroughLimit = decoded.getLookthroughLimit(); 2017 if (lookthroughLimit != null) 2018 { 2019 final String value; 2020 if (lookthroughLimit > 0L) 2021 { 2022 value = String.valueOf(lookthroughLimit); 2023 } 2024 else 2025 { 2026 value = INFO_RESULT_UTILS_GET_USER_RLIM_VALUE_UNLIMITED.get(); 2027 } 2028 2029 wrap(lines, INFO_RESULT_UTILS_GET_USER_RLIM_LOOKTHROUGH_LIMIT.get(value), 2030 indentPrefix, maxWidth); 2031 } 2032 2033 final String equivalentUserDN = decoded.getEquivalentAuthzUserDN(); 2034 if (equivalentUserDN != null) 2035 { 2036 wrap(lines, 2037 INFO_RESULT_UTILS_GET_USER_RLIM_EQUIVALENT_AUTHZ_USER_DN.get( 2038 equivalentUserDN), 2039 indentPrefix, maxWidth); 2040 } 2041 2042 final String ccpName = decoded.getClientConnectionPolicyName(); 2043 if (ccpName != null) 2044 { 2045 wrap(lines, INFO_RESULT_UTILS_GET_USER_RLIM_CCP_NAME.get(ccpName), 2046 indentPrefix, maxWidth); 2047 } 2048 2049 final String doubleIndentPrefix = indentPrefix + " "; 2050 final List<String> groupDNs = decoded.getGroupDNs(); 2051 if ((groupDNs != null) && (! groupDNs.isEmpty())) 2052 { 2053 wrap(lines, INFO_RESULT_UTILS_GET_USER_RLIM_GROUP_DNS_HEADER.get(), 2054 indentPrefix, maxWidth); 2055 for (final String groupDN : groupDNs) 2056 { 2057 wrap(lines, groupDN, doubleIndentPrefix, maxWidth); 2058 } 2059 } 2060 2061 final List<String> privilegeNames = decoded.getPrivilegeNames(); 2062 if ((privilegeNames != null) && (! privilegeNames.isEmpty())) 2063 { 2064 wrap(lines, INFO_RESULT_UTILS_GET_USER_RLIM_PRIVILEGES_HEADER.get(), 2065 indentPrefix, maxWidth); 2066 for (final String privilegeName : privilegeNames) 2067 { 2068 wrap(lines, privilegeName, doubleIndentPrefix, maxWidth); 2069 } 2070 } 2071 2072 final List<Attribute> otherAttrs = decoded.getOtherAttributes(); 2073 if ((otherAttrs != null) && (! otherAttrs.isEmpty())) 2074 { 2075 wrap(lines, INFO_RESULT_UTILS_GET_USER_RLIM_OTHER_ATTRIBUTES_HEADER.get(), 2076 indentPrefix, maxWidth); 2077 addLDIF(lines, new Entry("", otherAttrs), false, doubleIndentPrefix, 2078 maxWidth); 2079 } 2080 } 2081 2082 2083 2084 /** 2085 * Adds a multi-line string representation of the provided control, which is 2086 * expected to be an intermediate client response control, to the given list. 2087 * 2088 * @param lines The list to which the lines should be added. 2089 * @param c The control to be formatted. 2090 * @param prefix The prefix to use for each line. 2091 * @param maxWidth The maximum length of each line in characters, including 2092 * the comment prefix and indent. 2093 */ 2094 private static void addIntermediateClientResponseControl( 2095 final List<String> lines, final Control c, 2096 final String prefix, final int maxWidth) 2097 { 2098 final IntermediateClientResponseControl decoded; 2099 try 2100 { 2101 decoded = new IntermediateClientResponseControl(c.getOID(), 2102 c.isCritical(), c.getValue()); 2103 } 2104 catch (final Exception e) 2105 { 2106 Debug.debugException(e); 2107 addGenericResponseControl(lines, c, prefix, maxWidth); 2108 return; 2109 } 2110 2111 wrap(lines, INFO_RESULT_UTILS_INTERMEDIATE_CLIENT_HEADER.get(), prefix, 2112 maxWidth); 2113 2114 final String indentPrefix = prefix + " "; 2115 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 2116 indentPrefix, maxWidth); 2117 addIntermediateResponseValue(lines, decoded.getResponseValue(), 2118 indentPrefix, maxWidth); 2119 } 2120 2121 2122 2123 /** 2124 * Adds a multi-line string representation of the provided intermediate 2125 * response value to the given list. 2126 * 2127 * @param lines The list to which the lines should be added. 2128 * @param v The value to be formatted. 2129 * @param prefix The prefix to use for each line. 2130 * @param maxWidth The maximum length of each line in characters, including 2131 * the comment prefix and indent. 2132 */ 2133 private static void addIntermediateResponseValue(final List<String> lines, 2134 final IntermediateClientResponseValue v, 2135 final String prefix, final int maxWidth) 2136 { 2137 final String address = v.getUpstreamServerAddress(); 2138 if (address != null) 2139 { 2140 wrap(lines, 2141 INFO_RESULT_UTILS_INTERMEDIATE_CLIENT_UPSTREAM_ADDRESS.get(address), 2142 prefix, maxWidth); 2143 } 2144 2145 final Boolean secure = v.upstreamServerSecure(); 2146 if (secure != null) 2147 { 2148 wrap(lines, 2149 INFO_RESULT_UTILS_INTERMEDIATE_CLIENT_UPSTREAM_SECURE.get( 2150 String.valueOf(secure)), 2151 prefix, maxWidth); 2152 } 2153 2154 final String serverName = v.getServerName(); 2155 if (serverName != null) 2156 { 2157 wrap(lines, 2158 INFO_RESULT_UTILS_INTERMEDIATE_CLIENT_SERVER_NAME.get(serverName), 2159 prefix, maxWidth); 2160 } 2161 2162 final String sessionID = v.getServerSessionID(); 2163 if (sessionID != null) 2164 { 2165 wrap(lines, 2166 INFO_RESULT_UTILS_INTERMEDIATE_CLIENT_SESSION_ID.get(sessionID), 2167 prefix, maxWidth); 2168 } 2169 2170 final String responseID = v.getServerResponseID(); 2171 if (responseID != null) 2172 { 2173 wrap(lines, 2174 INFO_RESULT_UTILS_INTERMEDIATE_CLIENT_RESPONSE_ID.get(responseID), 2175 prefix, maxWidth); 2176 } 2177 2178 final IntermediateClientResponseValue upstreamResponse = 2179 v.getUpstreamResponse(); 2180 if (upstreamResponse != null) 2181 { 2182 wrap(lines, 2183 INFO_RESULT_UTILS_INTERMEDIATE_CLIENT_UPSTREAM_RESPONSE_HEADER.get(), 2184 prefix, maxWidth); 2185 addIntermediateResponseValue(lines, upstreamResponse, prefix + " ", 2186 maxWidth); 2187 } 2188 } 2189 2190 2191 2192 /** 2193 * Adds a multi-line string representation of the provided control, which is 2194 * expected to be a join result control, to the given list. 2195 * 2196 * @param lines The list to which the lines should be added. 2197 * @param c The control to be formatted. 2198 * @param prefix The prefix to use for each line. 2199 * @param maxWidth The maximum length of each line in characters, including 2200 * the comment prefix and indent. 2201 */ 2202 private static void addJoinResultControl( 2203 final List<String> lines, final Control c, 2204 final String prefix, final int maxWidth) 2205 { 2206 final JoinResultControl decoded; 2207 try 2208 { 2209 decoded = new JoinResultControl(c.getOID(), c.isCritical(), c.getValue()); 2210 } 2211 catch (final Exception e) 2212 { 2213 Debug.debugException(e); 2214 addGenericResponseControl(lines, c, prefix, maxWidth); 2215 return; 2216 } 2217 2218 wrap(lines, INFO_RESULT_UTILS_JOIN_HEADER.get(), prefix, 2219 maxWidth); 2220 2221 final String indentPrefix = prefix + " "; 2222 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 2223 indentPrefix, maxWidth); 2224 2225 final ResultCode resultCode = decoded.getResultCode(); 2226 if (resultCode != null) 2227 { 2228 wrap(lines, 2229 INFO_RESULT_UTILS_JOIN_RESULT_CODE.get( 2230 String.valueOf(resultCode)), 2231 indentPrefix, maxWidth); 2232 } 2233 2234 final String diagnosticMessage = decoded.getDiagnosticMessage(); 2235 if (diagnosticMessage != null) 2236 { 2237 wrap(lines, 2238 INFO_RESULT_UTILS_JOIN_DIAGNOSTIC_MESSAGE.get(diagnosticMessage), 2239 indentPrefix, maxWidth); 2240 } 2241 2242 final String matchedDN = decoded.getMatchedDN(); 2243 if (matchedDN != null) 2244 { 2245 wrap(lines, INFO_RESULT_UTILS_JOIN_MATCHED_DN.get(matchedDN), 2246 indentPrefix, maxWidth); 2247 } 2248 2249 final List<String> referralURLs = decoded.getReferralURLs(); 2250 if (referralURLs != null) 2251 { 2252 for (final String referralURL : referralURLs) 2253 { 2254 wrap(lines, INFO_RESULT_UTILS_JOIN_REFERRAL_URL.get(referralURL), 2255 indentPrefix, maxWidth); 2256 } 2257 } 2258 2259 final List<JoinedEntry> joinedEntries = decoded.getJoinResults(); 2260 if (joinedEntries != null) 2261 { 2262 for (final JoinedEntry e : joinedEntries) 2263 { 2264 addJoinedEntry(lines, e, indentPrefix, maxWidth); 2265 } 2266 } 2267 } 2268 2269 2270 2271 /** 2272 * Adds a multi-line string representation of the provided joined entry to the 2273 * given list. 2274 * 2275 * @param lines The list to which the lines should be added. 2276 * @param joinedEntry The joined entry to be formatted. 2277 * @param prefix The prefix to use for each line. 2278 * @param maxWidth The maximum length of each line in characters, 2279 * including the comment prefix and indent. 2280 */ 2281 private static void addJoinedEntry(final List<String> lines, 2282 final JoinedEntry joinedEntry, 2283 final String prefix, final int maxWidth) 2284 { 2285 wrap(lines, INFO_RESULT_UTILS_JOINED_WITH_ENTRY_HEADER.get(), prefix, 2286 maxWidth); 2287 addLDIF(lines, joinedEntry, true, prefix + " ", maxWidth); 2288 2289 final List<JoinedEntry> nestedJoinResults = 2290 joinedEntry.getNestedJoinResults(); 2291 if (nestedJoinResults != null) 2292 { 2293 for (final JoinedEntry e : nestedJoinResults) 2294 { 2295 addJoinedEntry(lines, e, prefix + " ", maxWidth); 2296 } 2297 } 2298 } 2299 2300 2301 2302 /** 2303 * Adds a multi-line string representation of the provided control, which is 2304 * expected to be a matching entry count response control, to the given list. 2305 * 2306 * @param lines The list to which the lines should be added. 2307 * @param c The control to be formatted. 2308 * @param prefix The prefix to use for each line. 2309 * @param maxWidth The maximum length of each line in characters, including 2310 * the comment prefix and indent. 2311 */ 2312 private static void addMatchingEntryCountResponseControl( 2313 final List<String> lines, final Control c, 2314 final String prefix, final int maxWidth) 2315 { 2316 final MatchingEntryCountResponseControl decoded; 2317 try 2318 { 2319 decoded = new MatchingEntryCountResponseControl(c.getOID(), 2320 c.isCritical(), c.getValue()); 2321 } 2322 catch (final Exception e) 2323 { 2324 Debug.debugException(e); 2325 addGenericResponseControl(lines, c, prefix, maxWidth); 2326 return; 2327 } 2328 2329 wrap(lines, INFO_RESULT_UTILS_MATCHING_ENTRY_COUNT_HEADER.get(), prefix, 2330 maxWidth); 2331 2332 final String indentPrefix = prefix + " "; 2333 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 2334 indentPrefix, maxWidth); 2335 2336 switch (decoded.getCountType()) 2337 { 2338 case EXAMINED_COUNT: 2339 wrap(lines, INFO_RESULT_UTILS_MATCHING_ENTRY_COUNT_TYPE_EXAMINED.get(), 2340 indentPrefix, maxWidth); 2341 wrap(lines, 2342 INFO_RESULT_UTILS_MATCHING_ENTRY_COUNT_VALUE.get( 2343 decoded.getCountValue()), 2344 indentPrefix, maxWidth); 2345 break; 2346 2347 case UNEXAMINED_COUNT: 2348 wrap(lines, 2349 INFO_RESULT_UTILS_MATCHING_ENTRY_COUNT_TYPE_UNEXAMINED.get(), 2350 indentPrefix, maxWidth); 2351 wrap(lines, 2352 INFO_RESULT_UTILS_MATCHING_ENTRY_COUNT_VALUE.get( 2353 decoded.getCountValue()), 2354 indentPrefix, maxWidth); 2355 break; 2356 2357 case UPPER_BOUND: 2358 wrap(lines, 2359 INFO_RESULT_UTILS_MATCHING_ENTRY_COUNT_TYPE_UPPER_BOUND.get(), 2360 indentPrefix, maxWidth); 2361 wrap(lines, 2362 INFO_RESULT_UTILS_MATCHING_ENTRY_COUNT_VALUE.get( 2363 decoded.getCountValue()), 2364 indentPrefix, maxWidth); 2365 break; 2366 2367 case UNKNOWN: 2368 default: 2369 wrap(lines, INFO_RESULT_UTILS_MATCHING_ENTRY_COUNT_TYPE_UNKNOWN.get(), 2370 indentPrefix, maxWidth); 2371 break; 2372 } 2373 2374 wrap(lines, 2375 INFO_RESULT_UTILS_MATCHING_ENTRY_COUNT_INDEXED.get( 2376 decoded.searchIndexed()), 2377 indentPrefix, maxWidth); 2378 2379 final List<String> debugInfo = decoded.getDebugInfo(); 2380 if ((debugInfo != null) && (! debugInfo.isEmpty())) 2381 { 2382 wrap(lines, INFO_RESULT_UTILS_MATCHING_ENTRY_COUNT_DEBUG_HEADER.get(), 2383 indentPrefix, maxWidth); 2384 for (final String s : debugInfo) 2385 { 2386 wrap(lines, s, indentPrefix + " ", maxWidth); 2387 } 2388 } 2389 } 2390 2391 2392 2393 /** 2394 * Adds a multi-line string representation of the provided control, which is 2395 * expected to be password policy response control, to the given list. 2396 * 2397 * @param lines The list to which the lines should be added. 2398 * @param c The control to be formatted. 2399 * @param prefix The prefix to use for each line. 2400 * @param maxWidth The maximum length of each line in characters, including 2401 * the comment prefix and indent. 2402 */ 2403 private static void addPasswordPolicyResponseControl( 2404 final List<String> lines, final Control c, 2405 final String prefix, final int maxWidth) 2406 { 2407 final PasswordPolicyResponseControl decoded; 2408 try 2409 { 2410 decoded = new PasswordPolicyResponseControl(c.getOID(), c.isCritical(), 2411 c.getValue()); 2412 } 2413 catch (final Exception e) 2414 { 2415 Debug.debugException(e); 2416 addGenericResponseControl(lines, c, prefix, maxWidth); 2417 return; 2418 } 2419 2420 wrap(lines, INFO_RESULT_UTILS_PW_POLICY_HEADER.get(), prefix, maxWidth); 2421 2422 final String indentPrefix = prefix + " "; 2423 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 2424 indentPrefix, maxWidth); 2425 2426 final PasswordPolicyErrorType errorType = decoded.getErrorType(); 2427 if (errorType == null) 2428 { 2429 wrap(lines, INFO_RESULT_UTILS_PW_POLICY_ERROR_TYPE_NONE.get(), 2430 indentPrefix, maxWidth); 2431 } 2432 else 2433 { 2434 wrap(lines, 2435 INFO_RESULT_UTILS_PW_POLICY_ERROR_TYPE.get(errorType.getName()), 2436 indentPrefix, maxWidth); 2437 } 2438 2439 final PasswordPolicyWarningType warningType = decoded.getWarningType(); 2440 if (warningType == null) 2441 { 2442 wrap(lines, INFO_RESULT_UTILS_PW_POLICY_WARNING_TYPE_NONE.get(), 2443 indentPrefix, maxWidth); 2444 } 2445 else 2446 { 2447 wrap(lines, 2448 INFO_RESULT_UTILS_PW_POLICY_WARNING_TYPE.get(warningType.getName()), 2449 indentPrefix, maxWidth); 2450 wrap(lines, 2451 INFO_RESULT_UTILS_PW_POLICY_WARNING_VALUE.get( 2452 decoded.getWarningValue()), 2453 indentPrefix, maxWidth); 2454 } 2455 } 2456 2457 2458 2459 /** 2460 * Adds a multi-line string representation of the provided control, which is 2461 * expected to be a password validation details response control, to the given 2462 * list. 2463 * 2464 * @param lines The list to which the lines should be added. 2465 * @param c The control to be formatted. 2466 * @param prefix The prefix to use for each line. 2467 * @param maxWidth The maximum length of each line in characters, including 2468 * the comment prefix and indent. 2469 */ 2470 private static void addPasswordValidationDetailsResponseControl( 2471 final List<String> lines, final Control c, 2472 final String prefix, final int maxWidth) 2473 { 2474 final PasswordValidationDetailsResponseControl decoded; 2475 try 2476 { 2477 decoded = new PasswordValidationDetailsResponseControl(c.getOID(), 2478 c.isCritical(), c.getValue()); 2479 } 2480 catch (final Exception e) 2481 { 2482 Debug.debugException(e); 2483 addGenericResponseControl(lines, c, prefix, maxWidth); 2484 return; 2485 } 2486 2487 wrap(lines, INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_HEADER.get(), prefix, 2488 maxWidth); 2489 2490 final String indentPrefix = prefix + " "; 2491 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 2492 indentPrefix, maxWidth); 2493 2494 switch (decoded.getResponseType()) 2495 { 2496 case VALIDATION_DETAILS: 2497 wrap(lines, 2498 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_RESULT_TYPE_RESULT.get(), 2499 indentPrefix, maxWidth); 2500 2501 final List<PasswordQualityRequirementValidationResult> results = 2502 decoded.getValidationResults(); 2503 if (results != null) 2504 { 2505 for (final PasswordQualityRequirementValidationResult r : results) 2506 { 2507 wrap(lines, 2508 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_PQR_HEADER.get(), 2509 indentPrefix + " ", maxWidth); 2510 2511 final String tripleIndentPrefix = indentPrefix + " "; 2512 final PasswordQualityRequirement pqr = r.getPasswordRequirement(); 2513 2514 final String description = pqr.getDescription(); 2515 if (description != null) 2516 { 2517 wrap(lines, 2518 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_PQR_DESC.get( 2519 description), 2520 tripleIndentPrefix, maxWidth); 2521 } 2522 2523 final String clientSideType = pqr.getClientSideValidationType(); 2524 if (clientSideType != null) 2525 { 2526 wrap(lines, 2527 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_PQR_TYPE.get( 2528 clientSideType), 2529 tripleIndentPrefix, maxWidth); 2530 } 2531 2532 final Map<String,String> properties = 2533 pqr.getClientSideValidationProperties(); 2534 if (properties != null) 2535 { 2536 for (final Map.Entry<String,String> e : properties.entrySet()) 2537 { 2538 wrap(lines, 2539 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_PQR_PROP.get( 2540 e.getKey(), e.getValue()), 2541 tripleIndentPrefix, maxWidth); 2542 } 2543 } 2544 2545 wrap(lines, 2546 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_PQR_SATISFIED.get( 2547 r.requirementSatisfied()), 2548 tripleIndentPrefix, maxWidth); 2549 2550 final String additionalInfo = r.getAdditionalInfo(); 2551 if (additionalInfo != null) 2552 { 2553 wrap(lines, 2554 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_PQR_INFO.get( 2555 additionalInfo), 2556 tripleIndentPrefix, maxWidth); 2557 } 2558 } 2559 } 2560 break; 2561 case NO_PASSWORD_PROVIDED: 2562 wrap(lines, 2563 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_RESULT_TYPE_NO_PW.get(), 2564 indentPrefix, maxWidth); 2565 break; 2566 case MULTIPLE_PASSWORDS_PROVIDED: 2567 wrap(lines, 2568 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_RESULT_TYPE_MULTIPLE_PW. 2569 get(), 2570 indentPrefix, maxWidth); 2571 break; 2572 case NO_VALIDATION_ATTEMPTED: 2573 wrap(lines, 2574 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_RESULT_TYPE_NO_VALIDATION. 2575 get(), 2576 indentPrefix, maxWidth); 2577 break; 2578 default: 2579 wrap(lines, 2580 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_RESULT_TYPE_DEFAULT.get( 2581 decoded.getResponseType().name()), 2582 indentPrefix, maxWidth); 2583 break; 2584 } 2585 2586 wrap(lines, 2587 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_MISSING_CURRENT.get( 2588 decoded.missingCurrentPassword()), 2589 indentPrefix, maxWidth); 2590 wrap(lines, 2591 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_MUST_CHANGE.get( 2592 decoded.mustChangePassword()), 2593 indentPrefix, maxWidth); 2594 2595 final Integer secondsUntilExpiration = decoded.getSecondsUntilExpiration(); 2596 if (secondsUntilExpiration != null) 2597 { 2598 wrap(lines, 2599 INFO_RESULT_UTILS_PW_VALIDATION_DETAILS_SECONDS_TO_EXP.get( 2600 secondsUntilExpiration), 2601 indentPrefix, maxWidth); 2602 } 2603 } 2604 2605 2606 2607 /** 2608 * Adds a multi-line string representation of the provided control, which is 2609 * expected to be a soft delete response control, to the given list. 2610 * 2611 * @param lines The list to which the lines should be added. 2612 * @param c The control to be formatted. 2613 * @param prefix The prefix to use for each line. 2614 * @param maxWidth The maximum length of each line in characters, including 2615 * the comment prefix and indent. 2616 */ 2617 private static void addSoftDeleteResponseControl( 2618 final List<String> lines, final Control c, 2619 final String prefix, final int maxWidth) 2620 { 2621 final SoftDeleteResponseControl decoded; 2622 try 2623 { 2624 decoded = new SoftDeleteResponseControl(c.getOID(), c.isCritical(), 2625 c.getValue()); 2626 } 2627 catch (final Exception e) 2628 { 2629 Debug.debugException(e); 2630 addGenericResponseControl(lines, c, prefix, maxWidth); 2631 return; 2632 } 2633 2634 wrap(lines, INFO_RESULT_UTILS_SOFT_DELETE_HEADER.get(), prefix, maxWidth); 2635 2636 final String indentPrefix = prefix + " "; 2637 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 2638 indentPrefix, maxWidth); 2639 2640 final String dn = decoded.getSoftDeletedEntryDN(); 2641 if (dn != null) 2642 { 2643 wrap(lines, INFO_RESULT_UTILS_SOFT_DELETED_DN.get(dn), indentPrefix, 2644 maxWidth); 2645 } 2646 } 2647 2648 2649 2650 /** 2651 * Adds a multi-line string representation of the provided control, which is 2652 * expected to be a transaction settings response control, to the given list. 2653 * 2654 * @param lines The list to which the lines should be added. 2655 * @param c The control to be formatted. 2656 * @param prefix The prefix to use for each line. 2657 * @param maxWidth The maximum length of each line in characters, including 2658 * the comment prefix and indent. 2659 */ 2660 private static void addTransactionSettingsResponseControl( 2661 final List<String> lines, final Control c, 2662 final String prefix, final int maxWidth) 2663 { 2664 final TransactionSettingsResponseControl decoded; 2665 try 2666 { 2667 decoded = new TransactionSettingsResponseControl(c.getOID(), 2668 c.isCritical(), c.getValue()); 2669 } 2670 catch (final Exception e) 2671 { 2672 Debug.debugException(e); 2673 addGenericResponseControl(lines, c, prefix, maxWidth); 2674 return; 2675 } 2676 2677 wrap(lines, INFO_RESULT_UTILS_TXN_SETTINGS_HEADER.get(), prefix, 2678 maxWidth); 2679 2680 final String indentPrefix = prefix + " "; 2681 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 2682 indentPrefix, maxWidth); 2683 wrap(lines, 2684 INFO_RESULT_UTILS_TXN_SETTINGS_NUM_CONFLICTS.get( 2685 decoded.getNumLockConflicts()), 2686 indentPrefix, maxWidth); 2687 wrap(lines, 2688 INFO_RESULT_UTILS_TXN_SETTINGS_BACKEND_LOCK_ACQUIRED.get( 2689 decoded.backendLockAcquired()), 2690 indentPrefix, maxWidth); 2691 } 2692 2693 2694 2695 /** 2696 * Adds a multi-line string representation of the provided control, which is 2697 * expected to be a uniqueness response control, to the given list. 2698 * 2699 * @param lines The list to which the lines should be added. 2700 * @param c The control to be formatted. 2701 * @param prefix The prefix to use for each line. 2702 * @param maxWidth The maximum length of each line in characters, including 2703 * the comment prefix and indent. 2704 */ 2705 private static void addUniquenessResponseControl( 2706 final List<String> lines, final Control c, 2707 final String prefix, final int maxWidth) 2708 { 2709 final UniquenessResponseControl decoded; 2710 try 2711 { 2712 decoded = new UniquenessResponseControl(c.getOID(), c.isCritical(), 2713 c.getValue()); 2714 } 2715 catch (final Exception e) 2716 { 2717 Debug.debugException(e); 2718 addGenericResponseControl(lines, c, prefix, maxWidth); 2719 return; 2720 } 2721 2722 wrap(lines, INFO_RESULT_UTILS_UNIQUENESS_HEADER.get(), prefix, maxWidth); 2723 2724 final String indentPrefix = prefix + " "; 2725 wrap(lines, INFO_RESULT_UTILS_RESPONSE_CONTROL_OID.get(c.getOID()), 2726 indentPrefix, maxWidth); 2727 wrap(lines, INFO_RESULT_UTILS_UNIQUENESS_ID.get(decoded.getUniquenessID()), 2728 indentPrefix, maxWidth); 2729 2730 final String preCommitStatus; 2731 if (decoded.getPreCommitValidationPassed() == null) 2732 { 2733 preCommitStatus = 2734 INFO_RESULT_UTILS_UNIQUENESS_STATUS_VALUE_NOT_ATTEMPTED.get(); 2735 } 2736 else if (decoded.getPreCommitValidationPassed() == Boolean.TRUE) 2737 { 2738 preCommitStatus = INFO_RESULT_UTILS_UNIQUENESS_STATUS_VALUE_PASSED.get(); 2739 } 2740 else 2741 { 2742 preCommitStatus = INFO_RESULT_UTILS_UNIQUENESS_STATUS_VALUE_FAILED.get(); 2743 } 2744 wrap(lines, 2745 INFO_RESULT_UTILS_UNIQUENESS_PRE_COMMIT_STATUS.get(preCommitStatus), 2746 indentPrefix, maxWidth); 2747 2748 final String postCommitStatus; 2749 if (decoded.getPostCommitValidationPassed() == null) 2750 { 2751 postCommitStatus = 2752 INFO_RESULT_UTILS_UNIQUENESS_STATUS_VALUE_NOT_ATTEMPTED.get(); 2753 } 2754 else if (decoded.getPostCommitValidationPassed() == Boolean.TRUE) 2755 { 2756 postCommitStatus = INFO_RESULT_UTILS_UNIQUENESS_STATUS_VALUE_PASSED.get(); 2757 } 2758 else 2759 { 2760 postCommitStatus = INFO_RESULT_UTILS_UNIQUENESS_STATUS_VALUE_FAILED.get(); 2761 } 2762 wrap(lines, 2763 INFO_RESULT_UTILS_UNIQUENESS_POST_COMMIT_STATUS.get(postCommitStatus), 2764 indentPrefix, maxWidth); 2765 2766 final String message = decoded.getValidationMessage(); 2767 if (message != null) 2768 { 2769 wrap(lines, INFO_RESULT_UTILS_UNIQUENESS_MESSAGE.get(message), 2770 indentPrefix, maxWidth); 2771 } 2772 } 2773 2774 2775 2776 /** 2777 * Creates a string that may be used as a prefix for all lines with the given 2778 * settings. 2779 * 2780 * @param comment Indicates whether to prefix each line with an octothorpe 2781 * to indicate that it is a comment. 2782 * @param indent The number of spaces to indent each line. 2783 * 2784 * @return A string that may be used as a prefix for all lines with the given 2785 * settings. 2786 */ 2787 private static String createPrefix(final boolean comment, final int indent) 2788 { 2789 // Generate a prefix that will be used for every line. 2790 final StringBuilder buffer = new StringBuilder(indent + 2); 2791 if (comment) 2792 { 2793 buffer.append("# "); 2794 } 2795 for (int i=0; i < indent; i++) 2796 { 2797 buffer.append(' '); 2798 } 2799 return buffer.toString(); 2800 } 2801 2802 2803 2804 /** 2805 * Adds a wrapped version of the provided string to the given list. 2806 * 2807 * @param lines The list to which the wrapped lines should be added. 2808 * @param s The string to be wrapped. 2809 * @param prefix The prefix to use at the beginning of each line. 2810 * @param maxWidth The maximum length of each line in characters. 2811 */ 2812 private static void wrap(final List<String> lines, final String s, 2813 final String prefix, final int maxWidth) 2814 { 2815 // If the maximum width is less than the prefix length + 20 characters, then 2816 // make it make that the new effective maximum width. 2817 final int minimumMaxWidth = prefix.length() + 20; 2818 final int effectiveMaxWidth = Math.max(minimumMaxWidth, maxWidth); 2819 2820 2821 // If the prefix plus the provided string is within the maximum width, then 2822 // there's no need to do any wrapping. 2823 if ((prefix.length() + s.length()) <= effectiveMaxWidth) 2824 { 2825 lines.add(prefix + s); 2826 return; 2827 } 2828 2829 2830 // Wrap the provided string. If it spans multiple lines, all lines except 2831 // the first will be indented an extra five spaces. 2832 final List<String> wrappedLines = StaticUtils.wrapLine(s, 2833 (maxWidth - prefix.length()), 2834 (maxWidth - prefix.length() - 5)); 2835 2836 2837 2838 // Add the wrapped lines to the given list. 2839 for (int i=0; i < wrappedLines.size(); i++) 2840 { 2841 if (i > 0) 2842 { 2843 lines.add(prefix + " " + wrappedLines.get(i)); 2844 } 2845 else 2846 { 2847 lines.add(prefix + wrappedLines.get(i)); 2848 } 2849 } 2850 } 2851 2852 2853 2854 /** 2855 * Adds the lines that comprise an LDIF representation of the provided entry 2856 * to the given list. 2857 * 2858 * @param lines The list to which the lines should be added. 2859 * @param entry The entry to be formatted. 2860 * @param includeDN Indicates whether to include the DN of the entry in the 2861 * resulting LDIF representation. 2862 * @param prefix The prefix to use at the beginning of each line. 2863 * @param maxWidth The maximum length of each line in characters. 2864 */ 2865 private static void addLDIF(final List<String> lines, final Entry entry, 2866 final boolean includeDN, final String prefix, 2867 final int maxWidth) 2868 { 2869 // Never use a wrap column that is less than 20 characters. 2870 final int wrapColumn = Math.max(maxWidth - prefix.length(), 20); 2871 2872 if (includeDN) 2873 { 2874 for (final String s : entry.toLDIF(wrapColumn)) 2875 { 2876 lines.add(prefix + s); 2877 } 2878 } 2879 else 2880 { 2881 final String[] ldifLinesWithDN; 2882 if (entry.getDN().length() > 10) 2883 { 2884 final Entry dup = entry.duplicate(); 2885 dup.setDN(""); 2886 ldifLinesWithDN = dup.toLDIF(wrapColumn); 2887 } 2888 else 2889 { 2890 ldifLinesWithDN = entry.toLDIF(wrapColumn); 2891 } 2892 2893 for (int i=1; i < ldifLinesWithDN.length; i++) 2894 { 2895 lines.add(prefix + ldifLinesWithDN[i]); 2896 } 2897 } 2898 } 2899}