001/* 002 * Copyright 2009-2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2015-2019 Ping Identity Corporation 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.sdk.unboundidds.tasks; 022 023 024 025import java.util.Arrays; 026import java.util.Collections; 027import java.util.Date; 028import java.util.LinkedHashMap; 029import java.util.LinkedList; 030import java.util.List; 031import java.util.Map; 032 033import com.unboundid.ldap.sdk.Attribute; 034import com.unboundid.ldap.sdk.Entry; 035import com.unboundid.ldap.sdk.Filter; 036import com.unboundid.ldap.sdk.LDAPException; 037import com.unboundid.ldap.sdk.SearchScope; 038import com.unboundid.util.Debug; 039import com.unboundid.util.NotMutable; 040import com.unboundid.util.StaticUtils; 041import com.unboundid.util.ThreadSafety; 042import com.unboundid.util.ThreadSafetyLevel; 043import com.unboundid.util.Validator; 044 045import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*; 046 047 048 049/** 050 * This class defines a Directory Server task that can be used to perform an 051 * internal search within the server and write the contents to an LDIF file. 052 * <BR> 053 * <BLOCKQUOTE> 054 * <B>NOTE:</B> This class, and other classes within the 055 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 056 * supported for use against Ping Identity, UnboundID, and 057 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 058 * for proprietary functionality or for external specifications that are not 059 * considered stable or mature enough to be guaranteed to work in an 060 * interoperable way with other types of LDAP servers. 061 * </BLOCKQUOTE> 062 * <BR> 063 * The properties that are available for use with this type of task include: 064 * <UL> 065 * <LI>The base DN to use for the search. This is required.</LI> 066 * <LI>The scope to use for the search. This is required.</LI> 067 * <LI>The filter to use for the search. This is required.</LI> 068 * <LI>The attributes to return. This is optional and multivalued.</LI> 069 * <LI>The authorization DN to use for the search. This is optional.</LI> 070 * <LI>The path to the output file to use. This is required.</LI> 071 * </UL> 072 */ 073@NotMutable() 074@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 075public final class SearchTask 076 extends Task 077{ 078 /** 079 * The fully-qualified name of the Java class that is used for the search 080 * task. 081 */ 082 static final String SEARCH_TASK_CLASS = 083 "com.unboundid.directory.server.tasks.SearchTask"; 084 085 086 087 /** 088 * The name of the attribute used to specify the search base DN. 089 */ 090 private static final String ATTR_BASE_DN = "ds-task-search-base-dn"; 091 092 093 094 /** 095 * The name of the attribute used to specify the search scope. 096 */ 097 private static final String ATTR_SCOPE = "ds-task-search-scope"; 098 099 100 101 /** 102 * The name of the attribute used to specify the search filter. 103 */ 104 private static final String ATTR_FILTER = "ds-task-search-filter"; 105 106 107 108 /** 109 * The name of the attribute used to specify the attribute(s) to return. 110 */ 111 private static final String ATTR_RETURN_ATTR = 112 "ds-task-search-return-attribute"; 113 114 115 116 /** 117 * The name of the attribute used to specify the authorization DN. 118 */ 119 private static final String ATTR_AUTHZ_DN = "ds-task-search-authz-dn"; 120 121 122 123 /** 124 * The name of the attribute used to specify the output file. 125 */ 126 private static final String ATTR_OUTPUT_FILE = "ds-task-search-output-file"; 127 128 129 130 /** 131 * The name of the object class used in search task entries. 132 */ 133 private static final String OC_SEARCH_TASK = "ds-task-search"; 134 135 136 137 /** 138 * The task property that will be used for the base DN. 139 */ 140 private static final TaskProperty PROPERTY_BASE_DN = 141 new TaskProperty(ATTR_BASE_DN, 142 INFO_SEARCH_TASK_DISPLAY_NAME_BASE_DN.get(), 143 INFO_SEARCH_TASK_DESCRIPTION_BASE_DN.get(), String.class, true, 144 false, false); 145 146 147 148 /** 149 * The allowed values for the scope property. 150 */ 151 private static final Object[] ALLOWED_SCOPE_VALUES = 152 { 153 "base", "baseobject", "0", 154 "one", "onelevel", "singlelevel", "1", 155 "sub", "subtree", "wholesubtree", "2", 156 "subord", "subordinate", "subordinatesubtree", "3" 157 }; 158 159 160 161 /** 162 * The task property that will be used for the scope. 163 */ 164 private static final TaskProperty PROPERTY_SCOPE = 165 new TaskProperty(ATTR_SCOPE, 166 INFO_SEARCH_TASK_DISPLAY_NAME_SCOPE.get(), 167 INFO_SEARCH_TASK_DESCRIPTION_SCOPE.get(), String.class, true, 168 false, false, ALLOWED_SCOPE_VALUES); 169 170 171 172 /** 173 * The task property that will be used for the filter. 174 */ 175 private static final TaskProperty PROPERTY_FILTER = 176 new TaskProperty(ATTR_FILTER, 177 INFO_SEARCH_TASK_DISPLAY_NAME_FILTER.get(), 178 INFO_SEARCH_TASK_DESCRIPTION_FILTER.get(), String.class, true, 179 false, false); 180 181 182 183 /** 184 * The task property that will be used for the requested attributes. 185 */ 186 private static final TaskProperty PROPERTY_REQUESTED_ATTR = 187 new TaskProperty(ATTR_RETURN_ATTR, 188 INFO_SEARCH_TASK_DISPLAY_NAME_RETURN_ATTR.get(), 189 INFO_SEARCH_TASK_DESCRIPTION_RETURN_ATTR.get(), String.class, false, 190 true, false); 191 192 193 194 /** 195 * The task property that will be used for the authorization DN. 196 */ 197 private static final TaskProperty PROPERTY_AUTHZ_DN = 198 new TaskProperty(ATTR_AUTHZ_DN, 199 INFO_SEARCH_TASK_DISPLAY_NAME_AUTHZ_DN.get(), 200 INFO_SEARCH_TASK_DESCRIPTION_AUTHZ_DN.get(), String.class, false, 201 false, true); 202 203 204 205 /** 206 * The task property that will be used for the output file. 207 */ 208 private static final TaskProperty PROPERTY_OUTPUT_FILE = 209 new TaskProperty(ATTR_OUTPUT_FILE, 210 INFO_SEARCH_TASK_DISPLAY_NAME_OUTPUT_FILE.get(), 211 INFO_SEARCH_TASK_DESCRIPTION_NAME_OUTPUT_FILE.get(), String.class, 212 true, false, false); 213 214 215 216 /** 217 * The serial version UID for this serializable class. 218 */ 219 private static final long serialVersionUID = -1742374271508548328L; 220 221 222 223 // The search filter. 224 private final Filter filter; 225 226 // The list of attributes to return. 227 private final List<String> attributes; 228 229 // The search scope. 230 private final SearchScope scope; 231 232 // The authorization DN. 233 private final String authzDN; 234 235 // The search base DN. 236 private final String baseDN; 237 238 // The output file path. 239 private final String outputFile; 240 241 242 243 /** 244 * Creates a new uninitialized search task instance which should only be used 245 * for obtaining general information about this task, including the task name, 246 * description, and supported properties. Attempts to use a task created with 247 * this constructor for any other reason will likely fail. 248 */ 249 public SearchTask() 250 { 251 filter = null; 252 attributes = null; 253 scope = null; 254 authzDN = null; 255 baseDN = null; 256 outputFile = null; 257 } 258 259 260 261 /** 262 * Creates a new search task with the provided information. 263 * 264 * @param taskID The task ID to use for this task. If it is 265 * {@code null} then a UUID will be generated for use as 266 * the task ID. 267 * @param baseDN The base DN to use for the search. It must not be 268 * {@code null}. 269 * @param scope The scope to use for the search. It must not be 270 * {@code null}. 271 * @param filter The filter to use for the search. It must not be 272 * {@code null}. 273 * @param attributes The list of attributes to include in matching entries. 274 * If it is {@code null} or empty, then all user 275 * attributes will be selected. 276 * @param outputFile The path to the file (on the server filesystem) to 277 * which the results should be written. It must not be 278 * {@code null}. 279 */ 280 public SearchTask(final String taskID, final String baseDN, 281 final SearchScope scope, final Filter filter, 282 final List<String> attributes, final String outputFile) 283 { 284 this(taskID, baseDN, scope, filter, attributes, outputFile, null, null, 285 null, null, null, null); 286 } 287 288 289 290 /** 291 * Creates a new search task with the provided information. 292 * 293 * @param taskID The task ID to use for this task. If it is 294 * {@code null} then a UUID will be generated for use as 295 * the task ID. 296 * @param baseDN The base DN to use for the search. It must not be 297 * {@code null}. 298 * @param scope The scope to use for the search. It must not be 299 * {@code null}. 300 * @param filter The filter to use for the search. It must not be 301 * {@code null}. 302 * @param attributes The list of attributes to include in matching entries. 303 * If it is {@code null} or empty, then all user 304 * attributes will be selected. 305 * @param outputFile The path to the file (on the server filesystem) to 306 * which the results should be written. It must not be 307 * {@code null}. 308 * @param authzDN The DN of the user as whom the search should be 309 * processed. If this is {@code null}, then it will be 310 * processed as an internal root user. 311 */ 312 public SearchTask(final String taskID, final String baseDN, 313 final SearchScope scope, final Filter filter, 314 final List<String> attributes, final String outputFile, 315 final String authzDN) 316 { 317 this(taskID, baseDN, scope, filter, attributes, outputFile, authzDN, null, 318 null, null, null, null); 319 } 320 321 322 323 /** 324 * Creates a new search task with the provided information. 325 * 326 * @param taskID The task ID to use for this task. If it is 327 * {@code null} then a UUID will be generated 328 * for use as the task ID. 329 * @param baseDN The base DN to use for the search. It must 330 * not be {@code null}. 331 * @param scope The scope to use for the search. It must 332 * not be {@code null}. 333 * @param filter The filter to use for the search. It must 334 * not be {@code null}. 335 * @param attributes The list of attributes to include in 336 * matching entries. If it is {@code null} or 337 * empty, then all user attributes will be 338 * selected. 339 * @param outputFile The path to the file (on the server 340 * filesystem) to which the results should be 341 * written. It must not be {@code null}. 342 * @param authzDN The DN of the user as whom the search 343 * should be processed. If this is 344 * {@code null}, then it will be processed as 345 * an internal root user. 346 * @param scheduledStartTime The time that this task should start 347 * running. 348 * @param dependencyIDs The list of task IDs that will be required 349 * to complete before this task will be 350 * eligible to start. 351 * @param failedDependencyAction Indicates what action should be taken if 352 * any of the dependencies for this task do 353 * not complete successfully. 354 * @param notifyOnCompletion The list of e-mail addresses of individuals 355 * that should be notified when this task 356 * completes. 357 * @param notifyOnError The list of e-mail addresses of individuals 358 * that should be notified if this task does 359 * not complete successfully. 360 */ 361 public SearchTask(final String taskID, final String baseDN, 362 final SearchScope scope, final Filter filter, 363 final List<String> attributes, final String outputFile, 364 final String authzDN, final Date scheduledStartTime, 365 final List<String> dependencyIDs, 366 final FailedDependencyAction failedDependencyAction, 367 final List<String> notifyOnCompletion, 368 final List<String> notifyOnError) 369 { 370 this(taskID, baseDN, scope, filter, attributes, outputFile, authzDN, 371 scheduledStartTime, dependencyIDs, failedDependencyAction, null, 372 notifyOnCompletion, null, notifyOnError, null, null, null); 373 } 374 375 376 377 /** 378 * Creates a new search task with the provided information. 379 * 380 * @param taskID The task ID to use for this task. If it is 381 * {@code null} then a UUID will be generated 382 * for use as the task ID. 383 * @param baseDN The base DN to use for the search. It must 384 * not be {@code null}. 385 * @param scope The scope to use for the search. It must 386 * not be {@code null}. 387 * @param filter The filter to use for the search. It must 388 * not be {@code null}. 389 * @param attributes The list of attributes to include in 390 * matching entries. If it is {@code null} or 391 * empty, then all user attributes will be 392 * selected. 393 * @param outputFile The path to the file (on the server 394 * filesystem) to which the results should be 395 * written. It must not be {@code null}. 396 * @param authzDN The DN of the user as whom the search 397 * should be processed. If this is 398 * {@code null}, then it will be processed as 399 * an internal root user. 400 * @param scheduledStartTime The time that this task should start 401 * running. 402 * @param dependencyIDs The list of task IDs that will be required 403 * to complete before this task will be 404 * eligible to start. 405 * @param failedDependencyAction Indicates what action should be taken if 406 * any of the dependencies for this task do 407 * not complete successfully. 408 * @param notifyOnStart The list of e-mail addresses of individuals 409 * that should be notified when this task 410 * starts running. 411 * @param notifyOnCompletion The list of e-mail addresses of individuals 412 * that should be notified when this task 413 * completes. 414 * @param notifyOnSuccess The list of e-mail addresses of individuals 415 * that should be notified if this task 416 * completes successfully. 417 * @param notifyOnError The list of e-mail addresses of individuals 418 * that should be notified if this task does 419 * not complete successfully. 420 * @param alertOnStart Indicates whether the server should send an 421 * alert notification when this task starts. 422 * @param alertOnSuccess Indicates whether the server should send an 423 * alert notification if this task completes 424 * successfully. 425 * @param alertOnError Indicates whether the server should send an 426 * alert notification if this task fails to 427 * complete successfully. 428 */ 429 public SearchTask(final String taskID, final String baseDN, 430 final SearchScope scope, final Filter filter, 431 final List<String> attributes, final String outputFile, 432 final String authzDN, final Date scheduledStartTime, 433 final List<String> dependencyIDs, 434 final FailedDependencyAction failedDependencyAction, 435 final List<String> notifyOnStart, 436 final List<String> notifyOnCompletion, 437 final List<String> notifyOnSuccess, 438 final List<String> notifyOnError, 439 final Boolean alertOnStart, final Boolean alertOnSuccess, 440 final Boolean alertOnError) 441 { 442 super(taskID, SEARCH_TASK_CLASS, scheduledStartTime, dependencyIDs, 443 failedDependencyAction, notifyOnStart, notifyOnCompletion, 444 notifyOnSuccess, notifyOnError, alertOnStart, alertOnSuccess, 445 alertOnError); 446 447 Validator.ensureNotNull(baseDN, scope, filter, outputFile); 448 449 this.baseDN = baseDN; 450 this.scope = scope; 451 this.filter = filter; 452 this.outputFile = outputFile; 453 this.authzDN = authzDN; 454 455 if (attributes == null) 456 { 457 this.attributes = Collections.emptyList(); 458 } 459 else 460 { 461 this.attributes = Collections.unmodifiableList(attributes); 462 } 463 } 464 465 466 467 /** 468 * Creates a new search task from the provided entry. 469 * 470 * @param entry The entry to use to create this search task. 471 * 472 * @throws TaskException If the provided entry cannot be parsed as a search 473 * task entry. 474 */ 475 public SearchTask(final Entry entry) 476 throws TaskException 477 { 478 super(entry); 479 480 481 // Get the base DN. It must be present. 482 baseDN = entry.getAttributeValue(ATTR_BASE_DN); 483 if (baseDN == null) 484 { 485 throw new TaskException(ERR_SEARCH_TASK_ENTRY_NO_BASE_DN.get( 486 entry.getDN())); 487 } 488 489 490 // Get the scope. It must be present. 491 final String scopeStr = 492 StaticUtils.toLowerCase(entry.getAttributeValue(ATTR_SCOPE)); 493 if (scopeStr == null) 494 { 495 throw new TaskException(ERR_SEARCH_TASK_ENTRY_NO_SCOPE.get( 496 entry.getDN())); 497 } 498 499 if (scopeStr.equals("base") || scopeStr.equals("baseobject") || 500 scopeStr.equals("0")) 501 { 502 scope = SearchScope.BASE; 503 } 504 else if (scopeStr.equals("one") || scopeStr.equals("onelevel") || 505 scopeStr.equals("singlelevel") || scopeStr.equals("1")) 506 { 507 scope = SearchScope.ONE; 508 } 509 else if (scopeStr.equals("sub") || scopeStr.equals("subtree") || 510 scopeStr.equals("wholesubtree") || scopeStr.equals("2")) 511 { 512 scope = SearchScope.SUB; 513 } 514 else if (scopeStr.equals("subord") || scopeStr.equals("subordinate") || 515 scopeStr.equals("subordinatesubtree") || scopeStr.equals("3")) 516 { 517 scope = SearchScope.SUBORDINATE_SUBTREE; 518 } 519 else 520 { 521 throw new TaskException(ERR_SEARCH_TASK_ENTRY_INVALID_SCOPE.get( 522 entry.getDN(), scopeStr)); 523 } 524 525 526 // Get the filter. It must be present. 527 final String filterStr = entry.getAttributeValue(ATTR_FILTER); 528 if (filterStr == null) 529 { 530 throw new TaskException(ERR_SEARCH_TASK_ENTRY_NO_FILTER.get( 531 entry.getDN())); 532 } 533 try 534 { 535 filter = Filter.create(filterStr); 536 } 537 catch (final LDAPException le) 538 { 539 Debug.debugException(le); 540 throw new TaskException(ERR_SEARCH_TASK_ENTRY_INVALID_FILTER.get( 541 entry.getDN(), filterStr), le); 542 } 543 544 545 // Get the list of requested attributes. It is optional. 546 final String[] attrs = entry.getAttributeValues(ATTR_RETURN_ATTR); 547 if (attrs == null) 548 { 549 attributes = Collections.emptyList(); 550 } 551 else 552 { 553 attributes = Collections.unmodifiableList(Arrays.asList(attrs)); 554 } 555 556 557 // Get the authorization DN. It is optional. 558 authzDN = entry.getAttributeValue(ATTR_AUTHZ_DN); 559 560 561 // Get the path to the output file. It must be present. 562 outputFile = entry.getAttributeValue(ATTR_OUTPUT_FILE); 563 if (outputFile == null) 564 { 565 throw new TaskException(ERR_SEARCH_TASK_ENTRY_NO_OUTPUT_FILE.get( 566 entry.getDN())); 567 } 568 } 569 570 571 572 /** 573 * Creates a new search task from the provided set of task properties. 574 * 575 * @param properties The set of task properties and their corresponding 576 * values to use for the task. It must not be 577 * {@code null}. 578 * 579 * @throws TaskException If the provided set of properties cannot be used to 580 * create a valid add schema file task. 581 */ 582 public SearchTask(final Map<TaskProperty,List<Object>> properties) 583 throws TaskException 584 { 585 super(SEARCH_TASK_CLASS, properties); 586 587 Filter tmpFilter = null; 588 SearchScope tmpScope = null; 589 String tmpAuthzDN = null; 590 String tmpBaseDN = null; 591 String tmpFile = null; 592 String[] tmpAttrs = null; 593 594 for (final Map.Entry<TaskProperty,List<Object>> entry : 595 properties.entrySet()) 596 { 597 final TaskProperty p = entry.getKey(); 598 final String attrName = StaticUtils.toLowerCase(p.getAttributeName()); 599 final List<Object> values = entry.getValue(); 600 601 if (attrName.equals(ATTR_BASE_DN)) 602 { 603 tmpBaseDN = parseString(p, values, null); 604 } 605 else if (attrName.equals(ATTR_SCOPE)) 606 { 607 final String scopeStr = 608 StaticUtils.toLowerCase(parseString(p, values, null)); 609 if (scopeStr != null) 610 { 611 if (scopeStr.equals("base") || scopeStr.equals("baseobject") || 612 scopeStr.equals("0")) 613 { 614 tmpScope = SearchScope.BASE; 615 } 616 else if (scopeStr.equals("one") || scopeStr.equals("onelevel") || 617 scopeStr.equals("singlelevel") || scopeStr.equals("1")) 618 { 619 tmpScope = SearchScope.ONE; 620 } 621 else if (scopeStr.equals("sub") || scopeStr.equals("subtree") || 622 scopeStr.equals("wholesubtree") || scopeStr.equals("2")) 623 { 624 tmpScope = SearchScope.SUB; 625 } 626 else if (scopeStr.equals("subord") || 627 scopeStr.equals("subordinate") || 628 scopeStr.equals("subordinatesubtree") || 629 scopeStr.equals("3")) 630 { 631 tmpScope = SearchScope.SUBORDINATE_SUBTREE; 632 } 633 else 634 { 635 throw new TaskException(ERR_SEARCH_TASK_INVALID_SCOPE_PROPERTY.get( 636 scopeStr)); 637 } 638 } 639 } 640 else if (attrName.equals(ATTR_FILTER)) 641 { 642 final String filterStr = parseString(p, values, null); 643 if (filterStr != null) 644 { 645 try 646 { 647 tmpFilter = Filter.create(filterStr); 648 } 649 catch (final LDAPException le) 650 { 651 Debug.debugException(le); 652 throw new TaskException(ERR_SEARCH_TASK_INVALID_FILTER_PROPERTY.get( 653 filterStr), le); 654 } 655 } 656 } 657 else if (attrName.equals(ATTR_RETURN_ATTR)) 658 { 659 tmpAttrs = parseStrings(p, values, null); 660 } 661 else if (attrName.equals(ATTR_OUTPUT_FILE)) 662 { 663 tmpFile = parseString(p, values, null); 664 } 665 else if (attrName.equals(ATTR_AUTHZ_DN)) 666 { 667 tmpAuthzDN = parseString(p, values, null); 668 } 669 } 670 671 baseDN = tmpBaseDN; 672 if (baseDN == null) 673 { 674 throw new TaskException(ERR_SEARCH_TASK_NO_BASE_PROPERTY.get()); 675 } 676 677 scope = tmpScope; 678 if (scope == null) 679 { 680 throw new TaskException(ERR_SEARCH_TASK_NO_SCOPE_PROPERTY.get()); 681 } 682 683 filter = tmpFilter; 684 if (filter == null) 685 { 686 throw new TaskException(ERR_SEARCH_TASK_NO_FILTER_PROPERTY.get()); 687 } 688 689 outputFile = tmpFile; 690 if (outputFile == null) 691 { 692 throw new TaskException(ERR_SEARCH_TASK_NO_OUTPUT_FILE_PROPERTY.get()); 693 } 694 695 696 if (tmpAttrs == null) 697 { 698 attributes = Collections.emptyList(); 699 } 700 else 701 { 702 attributes = Collections.unmodifiableList(Arrays.asList(tmpAttrs)); 703 } 704 705 authzDN = tmpAuthzDN; 706 } 707 708 709 710 /** 711 * {@inheritDoc} 712 */ 713 @Override() 714 public String getTaskName() 715 { 716 return INFO_TASK_NAME_SEARCH.get(); 717 } 718 719 720 721 /** 722 * {@inheritDoc} 723 */ 724 @Override() 725 public String getTaskDescription() 726 { 727 return INFO_TASK_DESCRIPTION_SEARCH.get(); 728 } 729 730 731 732 /** 733 * Retrieves the base DN for the search. 734 * 735 * @return The base DN for the search. 736 */ 737 public String getBaseDN() 738 { 739 return baseDN; 740 } 741 742 743 744 /** 745 * Retrieves the scope for the search. 746 * 747 * @return The scope for the search. 748 */ 749 public SearchScope getScope() 750 { 751 return scope; 752 } 753 754 755 756 /** 757 * Retrieves the filter for the search. 758 * 759 * @return The filter for the search. 760 */ 761 public Filter getFilter() 762 { 763 return filter; 764 } 765 766 767 768 /** 769 * Retrieves the list of attributes to include in matching entries. 770 * 771 * @return The list of attributes to include in matching entries, or an 772 * empty list of all user attributes should be requested. 773 */ 774 public List<String> getAttributes() 775 { 776 return attributes; 777 } 778 779 780 781 /** 782 * Retrieves the DN of the user as whom the request should be processed. 783 * 784 * @return The DN of the user as whom the request should be processed, or 785 * {@code null} if it should be processed as an internal root user. 786 */ 787 public String getAuthzDN() 788 { 789 return authzDN; 790 } 791 792 793 794 /** 795 * Retrieves the path to the file on the server filesystem to which the 796 * results should be written. 797 * 798 * @return The path to the file on the server filesystem to which the results 799 * should be written. 800 */ 801 public String getOutputFile() 802 { 803 return outputFile; 804 } 805 806 807 808 /** 809 * {@inheritDoc} 810 */ 811 @Override() 812 protected List<String> getAdditionalObjectClasses() 813 { 814 return Collections.singletonList(OC_SEARCH_TASK); 815 } 816 817 818 819 /** 820 * {@inheritDoc} 821 */ 822 @Override() 823 protected List<Attribute> getAdditionalAttributes() 824 { 825 final LinkedList<Attribute> attrs = new LinkedList<>(); 826 827 attrs.add(new Attribute(ATTR_BASE_DN, baseDN)); 828 attrs.add(new Attribute(ATTR_SCOPE, String.valueOf(scope.intValue()))); 829 attrs.add(new Attribute(ATTR_FILTER, filter.toString())); 830 attrs.add(new Attribute(ATTR_OUTPUT_FILE, outputFile)); 831 832 if ((attributes != null) && (! attributes.isEmpty())) 833 { 834 attrs.add(new Attribute(ATTR_RETURN_ATTR, attributes)); 835 } 836 837 if (authzDN != null) 838 { 839 attrs.add(new Attribute(ATTR_AUTHZ_DN, authzDN)); 840 } 841 842 return Collections.unmodifiableList(attrs); 843 } 844 845 846 847 /** 848 * {@inheritDoc} 849 */ 850 @Override() 851 public List<TaskProperty> getTaskSpecificProperties() 852 { 853 final LinkedList<TaskProperty> props = new LinkedList<>(); 854 855 props.add(PROPERTY_BASE_DN); 856 props.add(PROPERTY_SCOPE); 857 props.add(PROPERTY_FILTER); 858 props.add(PROPERTY_REQUESTED_ATTR); 859 props.add(PROPERTY_AUTHZ_DN); 860 props.add(PROPERTY_OUTPUT_FILE); 861 862 return Collections.unmodifiableList(props); 863 } 864 865 866 867 /** 868 * {@inheritDoc} 869 */ 870 @Override() 871 public Map<TaskProperty,List<Object>> getTaskPropertyValues() 872 { 873 final LinkedHashMap<TaskProperty,List<Object>> props = 874 new LinkedHashMap<>(StaticUtils.computeMapCapacity(6)); 875 876 props.put(PROPERTY_BASE_DN, 877 Collections.<Object>singletonList(baseDN)); 878 879 props.put(PROPERTY_SCOPE, 880 Collections.<Object>singletonList(String.valueOf(scope.intValue()))); 881 882 props.put(PROPERTY_FILTER, 883 Collections.<Object>singletonList(filter.toString())); 884 885 if ((attributes != null) && (! attributes.isEmpty())) 886 { 887 final LinkedList<Object> attrObjects = new LinkedList<>(); 888 attrObjects.addAll(attributes); 889 890 props.put(PROPERTY_REQUESTED_ATTR, 891 Collections.unmodifiableList(attrObjects)); 892 } 893 894 if (authzDN != null) 895 { 896 props.put(PROPERTY_AUTHZ_DN, 897 Collections.<Object>singletonList(authzDN)); 898 } 899 900 props.put(PROPERTY_OUTPUT_FILE, 901 Collections.<Object>singletonList(outputFile)); 902 903 props.putAll(super.getTaskPropertyValues()); 904 return Collections.unmodifiableMap(props); 905 } 906}