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