001/*
002 * Copyright 2009-2018 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2015-2018 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<>(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}