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