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