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}