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