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