001/*
002 * Copyright 2013-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.ArrayList;
026import java.util.Arrays;
027import java.util.Collections;
028import java.util.Date;
029import java.util.LinkedHashMap;
030import java.util.List;
031import java.util.Map;
032
033import com.unboundid.ldap.sdk.Attribute;
034import com.unboundid.ldap.sdk.Entry;
035import com.unboundid.util.NotMutable;
036import com.unboundid.util.ThreadSafety;
037import com.unboundid.util.ThreadSafetyLevel;
038
039import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*;
040import static com.unboundid.util.Validator.*;
041
042
043
044/**
045 * This class defines a Directory Server task that can be used to cause entries
046 * contained in a local DB backend to be re-encoded, which may be used to
047 * apply any configuration changes that affect the encoding of that entry (e.g.,
048 * if the entry should be encrypted, hashed, compressed, or fully or partially
049 * uncached; or if these settings should be reverted).
050 * <BR>
051 * <BLOCKQUOTE>
052 *   <B>NOTE:</B>  This class, and other classes within the
053 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
054 *   supported for use against Ping Identity, UnboundID, and Alcatel-Lucent 8661
055 *   server products.  These classes provide support for proprietary
056 *   functionality or for external specifications that are not considered stable
057 *   or mature enough to be guaranteed to work in an interoperable way with
058 *   other types of LDAP servers.
059 * </BLOCKQUOTE>
060 * <BR>
061 * The properties that are available for use with this type of task include:
062 * <UL>
063 *   <LI>The backend ID of the backend in which entries should be re-encoded.
064 *       This must be provided.</LI>
065 *   <LI>The base DN of a branch of entries to include in the re-encode
066 *       processing.</LI>
067 *   <LI>The base DN of a branch of entries to exclude from the re-encode
068 *       processing.</LI>
069 *   <LI>A filter to use to identify entries to include in the re-encode
070 *       processing.</LI>
071 *   <LI>A filter to use to identify entries to exclude from the re-encode
072 *       processing.</LI>
073 *   <LI>The maximum rate at which to re-encode entries, in number of entries
074 *       per second.</LI>
075 *   <LI>An indication as to whether to skip entries that are fully
076 *       uncached.</LI>
077 *   <LI>An indication as to whether to skip entries that are partially
078 *       uncached.</LI>
079 * </UL>
080 */
081@NotMutable()
082@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
083public final class ReEncodeEntriesTask
084       extends Task
085{
086  /**
087   * The fully-qualified name of the Java class that is used for the re-encode
088   * entries task.
089   */
090  static final String RE_ENCODE_ENTRIES_TASK_CLASS =
091       "com.unboundid.directory.server.tasks.ReEncodeEntriesTask";
092
093
094  /**
095   * The name of the attribute used to specify the backend ID containing the
096   * entries to re-encode.
097   */
098  private static final String ATTR_BACKEND_ID = "ds-task-reencode-backend-id";
099
100
101  /**
102   * The name of the attribute used to specify the include branch(es).
103   */
104  private static final String ATTR_INCLUDE_BRANCH =
105       "ds-task-reencode-include-branch";
106
107
108  /**
109   * The name of the attribute used to specify the exclude branch(es).
110   */
111  private static final String ATTR_EXCLUDE_BRANCH =
112       "ds-task-reencode-exclude-branch";
113
114
115  /**
116   * The name of the attribute used to specify the include filter(s).
117   */
118  private static final String ATTR_INCLUDE_FILTER =
119       "ds-task-reencode-include-filter";
120
121
122  /**
123   * The name of the attribute used to specify the exclude filter(s).
124   */
125  private static final String ATTR_EXCLUDE_FILTER =
126       "ds-task-reencode-exclude-filter";
127
128
129  /**
130   * The name of the attribute used to specify the maximum re-encode rate in
131   * entries per second.
132   */
133  private static final String ATTR_MAX_ENTRIES_PER_SECOND =
134       "ds-task-reencode-max-entries-per-second";
135
136
137  /**
138   * The name of the attribute used to specify whether to skip fully uncached
139   * entries.
140   */
141  private static final String ATTR_SKIP_FULLY_UNCACHED =
142       "ds-task-reencode-skip-fully-uncached-entries";
143
144
145  /**
146   * The name of the attribute used to specify whether to skip partially
147   * uncached entries.
148   */
149  private static final String ATTR_SKIP_PARTIALLY_UNCACHED =
150       "ds-task-reencode-skip-partially-uncached-entries";
151
152
153  /**
154   * The name of the object class used in re-encode entries task entries.
155   */
156  private static final String OC_REENCODE_ENTRIES_TASK =
157       "ds-task-reencode";
158
159
160  /**
161   * The task property that will be used for the backend ID.
162   */
163  static final TaskProperty PROPERTY_BACKEND_ID =
164       new TaskProperty(ATTR_BACKEND_ID,
165            INFO_DISPLAY_NAME_REENCODE_BACKEND_ID.get(),
166            INFO_DESCRIPTION_REENCODE_BACKEND_ID.get(),
167          String.class, true, false, false);
168
169
170
171  /**
172   * The task property that will be used for the include branch(es).
173   */
174  static final TaskProperty PROPERTY_INCLUDE_BRANCH =
175     new TaskProperty(ATTR_INCLUDE_BRANCH,
176          INFO_DISPLAY_NAME_REENCODE_INCLUDE_BRANCH.get(),
177          INFO_DESCRIPTION_REENCODE_INCLUDE_BRANCH.get(),
178          String.class, false, true, false);
179
180
181
182  /**
183   * The task property that will be used for the exclude branch(es).
184   */
185  static final TaskProperty PROPERTY_EXCLUDE_BRANCH =
186     new TaskProperty(ATTR_EXCLUDE_BRANCH,
187          INFO_DISPLAY_NAME_REENCODE_EXCLUDE_BRANCH.get(),
188          INFO_DESCRIPTION_REENCODE_EXCLUDE_BRANCH.get(),
189          String.class, false, true, false);
190
191
192
193  /**
194   * The task property that will be used for the include filter(s).
195   */
196  static final TaskProperty PROPERTY_INCLUDE_FILTER =
197     new TaskProperty(ATTR_INCLUDE_FILTER,
198          INFO_DISPLAY_NAME_REENCODE_INCLUDE_FILTER.get(),
199          INFO_DESCRIPTION_REENCODE_INCLUDE_FILTER.get(),
200          String.class, false, true, false);
201
202
203
204  /**
205   * The task property that will be used for the exclude filter(s).
206   */
207  static final TaskProperty PROPERTY_EXCLUDE_FILTER =
208     new TaskProperty(ATTR_EXCLUDE_FILTER,
209          INFO_DISPLAY_NAME_REENCODE_EXCLUDE_FILTER.get(),
210          INFO_DESCRIPTION_REENCODE_EXCLUDE_FILTER.get(),
211          String.class, false, true, false);
212
213
214
215  /**
216   * The task property that will be used for the maximum reencode rate.
217   */
218  static final TaskProperty PROPERTY_MAX_ENTRIES_PER_SECOND =
219     new TaskProperty(ATTR_MAX_ENTRIES_PER_SECOND,
220          INFO_DISPLAY_NAME_REENCODE_MAX_ENTRIES_PER_SECOND.get(),
221          INFO_DESCRIPTION_REENCODE_MAX_ENTRIES_PER_SECOND.get(),
222          Long.class, false, false, false);
223
224
225
226  /**
227   * The task property that will be used to indicate whether to skip fully
228   * uncached entries.
229   */
230  static final TaskProperty PROPERTY_SKIP_FULLY_UNCACHED=
231     new TaskProperty(ATTR_SKIP_FULLY_UNCACHED,
232          INFO_DISPLAY_NAME_REENCODE_SKIP_FULLY_UNCACHED.get(),
233          INFO_DESCRIPTION_REENCODE_SKIP_FULLY_UNCACHED.get(),
234          Boolean.class, false, false, false);
235
236
237
238  /**
239   * The task property that will be used to indicate whether to skip partially
240   * uncached entries.
241   */
242  static final TaskProperty PROPERTY_SKIP_PARTIALLY_UNCACHED=
243     new TaskProperty(ATTR_SKIP_PARTIALLY_UNCACHED,
244          INFO_DISPLAY_NAME_REENCODE_SKIP_PARTIALLY_UNCACHED.get(),
245          INFO_DESCRIPTION_REENCODE_SKIP_PARTIALLY_UNCACHED.get(),
246          Boolean.class, false, false, false);
247
248
249
250  /**
251   * The serial version UID for this serializable class.
252   */
253  private static final long serialVersionUID = 1804218099237094046L;
254
255
256
257  // Indicates whether to skip fully-uncached entries.
258  private final boolean skipFullyUncachedEntries;
259
260  // Indicates whether to skip partially-uncached entries.
261  private final boolean skipPartiallyUncachedEntries;
262
263  // The maximum number of entries to re-encode per second.
264  private final Long maxEntriesPerSecond;
265
266  // The list of exclude branch DNs.
267  private final List<String> excludeBranches;
268
269  // The list of exclude filters.
270  private final List<String> excludeFilters;
271
272  // The list of include branch DNs.
273  private final List<String> includeBranches;
274
275  // The list of include filters.
276  private final List<String> includeFilters;
277
278  // The backend ID for the backend containing entries to re-encode.
279  private final String backendID;
280
281
282
283  /**
284   * Creates a new uninitialized re-encode entries task instance which should
285   * only be used for obtaining general information about this task, including
286   * the task name, description, and supported properties.  Attempts to use a
287   * task created with this constructor for any other reason will likely fail.
288   */
289  public ReEncodeEntriesTask()
290  {
291    skipFullyUncachedEntries     = false;
292    skipPartiallyUncachedEntries = false;
293    maxEntriesPerSecond          = null;
294    excludeBranches              = null;
295    excludeFilters               = null;
296    includeBranches              = null;
297    includeFilters               = null;
298    backendID                    = null;
299  }
300
301
302
303
304  /**
305   * Creates a new re-encode entries task with the provided information.
306   *
307   * @param  taskID                        The task ID to use for this task.  If
308   *                                       it is {@code null} then a UUID will
309   *                                       be generated for use as the task ID.
310   * @param  backendID                     The backend ID of the backend
311   *                                       containing the entries to re-encode.
312   *                                       It must not be {@code null}.
313   * @param  includeBranches               A list containing the base DNs of
314   *                                       branches to include in re-encode
315   *                                       processing.  It may be {@code null}
316   *                                       or empty if there should not be any
317   *                                       include branches.
318   * @param  excludeBranches               A list containing the base DNs of
319   *                                       branches to exclude from re-encode
320   *                                       processing.  It may be {@code null}
321   *                                       or empty if there should not be any
322   *                                       exclude branches.
323   * @param  includeFilters                A list containing filters to use to
324   *                                       identify entries to include in
325   *                                       re-encode processing.  It may be
326   *                                       {@code null} or empty if there should
327   *                                       not be any include filters.
328   * @param  excludeFilters                A list containing filters to use to
329   *                                       identify entries to exclude from
330   *                                       re-encode processing.  It may be
331   *                                       {@code null} or empty if there should
332   *                                       not be any exclude filters.
333   * @param  maxEntriesPerSecond           The maximum number of entries to
334   *                                       re-encode per second.  It may be
335   *                                       {@code null} to indicate that no
336   *                                       limit should be imposed.
337   * @param  skipFullyUncachedEntries      Indicates whether to skip re-encode
338   *                                       processing for entries that are fully
339   *                                       uncached.
340   * @param  skipPartiallyUncachedEntries  Indicates whether to skip re-encode
341   *                                       processing for entries that contain
342   *                                       a mix of cached and uncached
343   *                                       attributes.
344   */
345  public ReEncodeEntriesTask(final String taskID,
346                             final String backendID,
347                             final List<String> includeBranches,
348                             final List<String> excludeBranches,
349                             final List<String> includeFilters,
350                             final List<String> excludeFilters,
351                             final Long maxEntriesPerSecond,
352                             final boolean skipFullyUncachedEntries,
353                             final boolean skipPartiallyUncachedEntries)
354  {
355    this(taskID, backendID, includeBranches, excludeBranches, includeFilters,
356         excludeFilters, maxEntriesPerSecond, skipFullyUncachedEntries,
357         skipPartiallyUncachedEntries, null, null, null, null, null);
358  }
359
360
361
362  /**
363   * Creates a new re-encode entries task with the provided information.
364   *
365   * @param  taskID                        The task ID to use for this task.  If
366   *                                       it is {@code null} then a UUID will
367   *                                       be generated for use as the task ID.
368   * @param  backendID                     The backend ID of the backend
369   *                                       containing the entries to re-encode.
370   *                                       It must not be {@code null}.
371   * @param  includeBranches               A list containing the base DNs of
372   *                                       branches to include in re-encode
373   *                                       processing.  It may be {@code null}
374   *                                       or empty if there should not be any
375   *                                       include branches.
376   * @param  excludeBranches               A list containing the base DNs of
377   *                                       branches to exclude from re-encode
378   *                                       processing.  It may be {@code null}
379   *                                       or empty if there should not be any
380   *                                       exclude branches.
381   * @param  includeFilters                A list containing filters to use to
382   *                                       identify entries to include in
383   *                                       re-encode processing.  It may be
384   *                                       {@code null} or empty if there should
385   *                                       not be any include filters.
386   * @param  excludeFilters                A list containing filters to use to
387   *                                       identify entries to exclude from
388   *                                       re-encode processing.  It may be
389   *                                       {@code null} or empty if there should
390   *                                       not be any exclude filters.
391   * @param  maxEntriesPerSecond           The maximum number of entries to
392   *                                       re-encode per second.  It may be
393   *                                       {@code null} to indicate that no
394   *                                       limit should be imposed.
395   * @param  skipFullyUncachedEntries      Indicates whether to skip re-encode
396   *                                       processing for entries that are fully
397   *                                       uncached.
398   * @param  skipPartiallyUncachedEntries  Indicates whether to skip re-encode
399   *                                       processing for entries that contain
400   *                                       a mix of cached and uncached
401   *                                       attributes.
402   * @param  scheduledStartTime            The time that this task should start
403   *                                       running.
404   * @param  dependencyIDs                 The list of task IDs that will be
405   *                                       required to complete before this task
406   *                                       will be eligible to start.
407   * @param  failedDependencyAction        Indicates what action should be taken
408   *                                       if any of the dependencies for this
409   *                                       task do not complete successfully.
410   * @param  notifyOnCompletion            The list of e-mail addresses of
411   *                                       individuals that should be notified
412   *                                       when this task completes.
413   * @param  notifyOnError                 The list of e-mail addresses of
414   *                                       individuals that should be notified
415   *                                       if this task does not complete
416   *                                       successfully.
417   */
418  public ReEncodeEntriesTask(final String taskID, final String backendID,
419              final List<String> includeBranches,
420              final List<String> excludeBranches,
421              final List<String> includeFilters,
422              final List<String> excludeFilters,
423              final Long maxEntriesPerSecond,
424              final boolean skipFullyUncachedEntries,
425              final boolean skipPartiallyUncachedEntries,
426              final Date scheduledStartTime,
427              final List<String> dependencyIDs,
428              final FailedDependencyAction failedDependencyAction,
429              final List<String> notifyOnCompletion,
430              final List<String> notifyOnError)
431  {
432    super(taskID, RE_ENCODE_ENTRIES_TASK_CLASS, scheduledStartTime,
433         dependencyIDs, failedDependencyAction, notifyOnCompletion,
434         notifyOnError);
435
436    ensureNotNull(backendID);
437
438    this.backendID                    = backendID;
439    this.maxEntriesPerSecond          = maxEntriesPerSecond;
440    this.skipFullyUncachedEntries     = skipFullyUncachedEntries;
441    this.skipPartiallyUncachedEntries = skipPartiallyUncachedEntries;
442
443    if ((includeBranches == null) || includeBranches.isEmpty())
444    {
445      this.includeBranches = Collections.emptyList();
446    }
447    else
448    {
449      this.includeBranches = Collections.unmodifiableList(includeBranches);
450    }
451
452    if ((excludeBranches == null) || excludeBranches.isEmpty())
453    {
454      this.excludeBranches = Collections.emptyList();
455    }
456    else
457    {
458      this.excludeBranches = Collections.unmodifiableList(excludeBranches);
459    }
460
461    if ((includeFilters == null) || includeFilters.isEmpty())
462    {
463      this.includeFilters = Collections.emptyList();
464    }
465    else
466    {
467      this.includeFilters = Collections.unmodifiableList(includeFilters);
468    }
469
470    if ((excludeFilters == null) || excludeFilters.isEmpty())
471    {
472      this.excludeFilters = Collections.emptyList();
473    }
474    else
475    {
476      this.excludeFilters = Collections.unmodifiableList(excludeFilters);
477    }
478  }
479
480
481
482  /**
483   * Creates a new re-encode entries task from the provided entry.
484   *
485   * @param  entry  The entry to use to create this re-encode entries task.
486   *
487   * @throws  TaskException  If the provided entry cannot be parsed as a
488   *                         re-encode entries task entry.
489   */
490  public ReEncodeEntriesTask(final Entry entry)
491         throws TaskException
492  {
493    super(entry);
494
495
496    // Get the backend ID.  It must be present.
497    backendID = entry.getAttributeValue(ATTR_BACKEND_ID);
498    if (backendID == null)
499    {
500      throw new TaskException(ERR_REENCODE_TASK_MISSING_REQUIRED_ATTR.get(
501           entry.getDN(), ATTR_BACKEND_ID));
502    }
503
504    // Get the set of include branches.
505    final String[] iBranches = entry.getAttributeValues(ATTR_INCLUDE_BRANCH);
506    if (iBranches == null)
507    {
508      includeBranches = Collections.emptyList();
509    }
510    else
511    {
512      includeBranches = Collections.unmodifiableList(Arrays.asList(iBranches));
513    }
514
515    // Get the set of exclude branches.
516    final String[] eBranches = entry.getAttributeValues(ATTR_EXCLUDE_BRANCH);
517    if (eBranches == null)
518    {
519      excludeBranches = Collections.emptyList();
520    }
521    else
522    {
523      excludeBranches = Collections.unmodifiableList(Arrays.asList(eBranches));
524    }
525
526    // Get the set of include filters.
527    final String[] iFilters = entry.getAttributeValues(ATTR_INCLUDE_FILTER);
528    if (iFilters == null)
529    {
530      includeFilters = Collections.emptyList();
531    }
532    else
533    {
534      includeFilters = Collections.unmodifiableList(Arrays.asList(iFilters));
535    }
536
537    // Get the set of exclude filters.
538    final String[] eFilters = entry.getAttributeValues(ATTR_EXCLUDE_FILTER);
539    if (eFilters == null)
540    {
541      excludeFilters = Collections.emptyList();
542    }
543    else
544    {
545      excludeFilters = Collections.unmodifiableList(Arrays.asList(eFilters));
546    }
547
548    // Get the max entry rate.
549    maxEntriesPerSecond =
550         entry.getAttributeValueAsLong(ATTR_MAX_ENTRIES_PER_SECOND);
551
552    // Determine whether to skip fully uncached entries.
553    final Boolean skipFullyUncached =
554         entry.getAttributeValueAsBoolean(ATTR_SKIP_FULLY_UNCACHED);
555    if (skipFullyUncached == null)
556    {
557      skipFullyUncachedEntries = false;
558    }
559    else
560    {
561      skipFullyUncachedEntries = skipFullyUncached;
562    }
563
564    // Determine whether to skip partially uncached entries.
565    final Boolean skipPartiallyUncached =
566         entry.getAttributeValueAsBoolean(ATTR_SKIP_PARTIALLY_UNCACHED);
567    if (skipPartiallyUncached == null)
568    {
569      skipPartiallyUncachedEntries = false;
570    }
571    else
572    {
573      skipPartiallyUncachedEntries = skipPartiallyUncached;
574    }
575  }
576
577
578
579  /**
580   * Creates a new re-encode entries task from the provided set of task
581   * properties.
582   *
583   * @param  properties  The set of task properties and their corresponding
584   *                     values to use for the task.  It must not be
585   *                     {@code null}.
586   *
587   * @throws  TaskException  If the provided set of properties cannot be used to
588   *                         create a valid re-encode entries task.
589   */
590  public ReEncodeEntriesTask(final Map<TaskProperty,List<Object>> properties)
591         throws TaskException
592  {
593    super(RE_ENCODE_ENTRIES_TASK_CLASS, properties);
594
595    boolean      skipFullyUncached     = false;
596    boolean      skipPartiallyUncached = false;
597    Long         maxRate               = null;
598    List<String> eBranches             = Collections.emptyList();
599    List<String> eFilters              = Collections.emptyList();
600    List<String> iBranches             = Collections.emptyList();
601    List<String> iFilters              = Collections.emptyList();
602    String       id                    = null;
603
604    for (final Map.Entry<TaskProperty,List<Object>> e : properties.entrySet())
605    {
606      final TaskProperty p = e.getKey();
607      final String attrName = p.getAttributeName();
608      final List<Object> values = e.getValue();
609
610      if (attrName.equalsIgnoreCase(ATTR_BACKEND_ID))
611      {
612        id = parseString(p, values, null);
613      }
614      else if (attrName.equalsIgnoreCase(ATTR_INCLUDE_BRANCH))
615      {
616        final String[] branches = parseStrings(p, values, null);
617        if (branches != null)
618        {
619          iBranches = Collections.unmodifiableList(Arrays.asList(branches));
620        }
621      }
622      else if (attrName.equalsIgnoreCase(ATTR_EXCLUDE_BRANCH))
623      {
624        final String[] branches = parseStrings(p, values, null);
625        if (branches != null)
626        {
627          eBranches = Collections.unmodifiableList(Arrays.asList(branches));
628        }
629      }
630      else if (attrName.equalsIgnoreCase(ATTR_INCLUDE_FILTER))
631      {
632        final String[] filters = parseStrings(p, values, null);
633        if (filters != null)
634        {
635          iFilters = Collections.unmodifiableList(Arrays.asList(filters));
636        }
637      }
638      else if (attrName.equalsIgnoreCase(ATTR_EXCLUDE_FILTER))
639      {
640        final String[] filters = parseStrings(p, values, null);
641        if (filters != null)
642        {
643          eFilters = Collections.unmodifiableList(Arrays.asList(filters));
644        }
645      }
646      else if (attrName.equalsIgnoreCase(ATTR_MAX_ENTRIES_PER_SECOND))
647      {
648        maxRate = parseLong(p, values, null);
649      }
650      else if (attrName.equalsIgnoreCase(ATTR_SKIP_FULLY_UNCACHED))
651      {
652        skipFullyUncached = parseBoolean(p, values, false);
653      }
654      else if (attrName.equalsIgnoreCase(ATTR_SKIP_PARTIALLY_UNCACHED))
655      {
656        skipPartiallyUncached = parseBoolean(p, values, false);
657      }
658    }
659
660    if (id == null)
661    {
662      throw new TaskException(ERR_REENCODE_TASK_MISSING_REQUIRED_PROPERTY.get(
663           ATTR_BACKEND_ID));
664    }
665
666    backendID                    = id;
667    includeBranches              = iBranches;
668    excludeBranches              = eBranches;
669    includeFilters               = iFilters;
670    excludeFilters               = eFilters;
671    maxEntriesPerSecond          = maxRate;
672    skipFullyUncachedEntries     = skipFullyUncached;
673    skipPartiallyUncachedEntries = skipPartiallyUncached;
674  }
675
676
677
678  /**
679   * {@inheritDoc}
680   */
681  @Override()
682  public String getTaskName()
683  {
684    return INFO_TASK_NAME_REENCODE_ENTRIES.get();
685  }
686
687
688
689  /**
690   * {@inheritDoc}
691   */
692  @Override()
693  public String getTaskDescription()
694  {
695    return INFO_TASK_DESCRIPTION_REENCODE_ENTRIES.get();
696  }
697
698
699
700  /**
701   * Retrieves the backend ID for the backend containing the entries to
702   * re-encode.
703   *
704   * @return  The backend ID for the backend containing the entries to
705   *          re-encode.
706   */
707  public String getBackendID()
708  {
709    return backendID;
710  }
711
712
713
714  /**
715   * Retrieves the base DNs of the branches to include in re-encode processing,
716   * if defined.
717   *
718   * @return  The base DNs of the branches to include in re-encode processing,
719   *          or an empty list if there should not be any include branches.
720   */
721  public List<String> getIncludeBranches()
722  {
723    return includeBranches;
724  }
725
726
727
728  /**
729   * Retrieves the base DNs of the branches to exclude from re-encode
730   * processing, if defined.
731   *
732   * @return  The base DNs of the branches to exclude from re-encode processing,
733   *          or an empty list if there should not be any exclude branches.
734   */
735  public List<String> getExcludeBranches()
736  {
737    return excludeBranches;
738  }
739
740
741
742  /**
743   * Retrieves a set of filters to use to identify entries to include in
744   * re-encode processing, if defined.
745   *
746   * @return  A set of filters to use to identify entries to include in
747   *          re-encode processing, or an empty list if there should not be any
748   *          include filters.
749   */
750  public List<String> getIncludeFilters()
751  {
752    return includeFilters;
753  }
754
755
756
757  /**
758   * Retrieves a set of filters to use to identify entries to exclude from
759   * re-encode processing, if defined.
760   *
761   * @return  A set of filters to use to identify entries to exclude from
762   *          re-encode processing, or an empty list if there should not be any
763   *          exclude filters.
764   */
765  public List<String> getExcludeFilters()
766  {
767    return excludeFilters;
768  }
769
770
771
772  /**
773   * Retrieves the maximum number of entries that should be re-encoded per
774   * second, if defined.
775   *
776   * @return  The maximum number of entries that should be re-encoded per
777   *          second, or {@code null} if no rate limit should be imposed.
778   */
779  public Long getMaxEntriesPerSecond()
780  {
781    return maxEntriesPerSecond;
782  }
783
784
785
786  /**
787   * Indicates whether to skip re-encode processing for entries that are stored
788   * as fully uncached.
789   *
790   * @return  {@code true} if fully uncached entries should be skipped, or
791   *          {@code false} if not.
792   */
793  public boolean skipFullyUncachedEntries()
794  {
795    return skipFullyUncachedEntries;
796  }
797
798
799
800  /**
801   * Indicates whether to skip re-encode processing for entries that have a
802   * mix of cached and uncached attributes.
803   *
804   * @return  {@code true} if partially uncached entries should be skipped, or
805   *          {@code false} if not.
806   */
807  public boolean skipPartiallyUncachedEntries()
808  {
809    return skipPartiallyUncachedEntries;
810  }
811
812
813
814  /**
815   * {@inheritDoc}
816   */
817  @Override()
818  protected List<String> getAdditionalObjectClasses()
819  {
820    return Arrays.asList(OC_REENCODE_ENTRIES_TASK);
821  }
822
823
824
825  /**
826   * {@inheritDoc}
827   */
828  @Override()
829  protected List<Attribute> getAdditionalAttributes()
830  {
831    final ArrayList<Attribute> attrList = new ArrayList<Attribute>(7);
832    attrList.add(new Attribute(ATTR_BACKEND_ID, backendID));
833    attrList.add(new Attribute(ATTR_SKIP_FULLY_UNCACHED,
834         String.valueOf(skipFullyUncachedEntries)));
835    attrList.add(new Attribute(ATTR_SKIP_PARTIALLY_UNCACHED,
836         String.valueOf(skipPartiallyUncachedEntries)));
837
838    if (! includeBranches.isEmpty())
839    {
840      attrList.add(new Attribute(ATTR_INCLUDE_BRANCH, includeBranches));
841    }
842
843    if (! excludeBranches.isEmpty())
844    {
845      attrList.add(new Attribute(ATTR_EXCLUDE_BRANCH, excludeBranches));
846    }
847
848    if (! includeFilters.isEmpty())
849    {
850      attrList.add(new Attribute(ATTR_INCLUDE_FILTER, includeFilters));
851    }
852
853    if (! excludeFilters.isEmpty())
854    {
855      attrList.add(new Attribute(ATTR_EXCLUDE_FILTER, excludeFilters));
856    }
857
858    if (maxEntriesPerSecond != null)
859    {
860      attrList.add(new Attribute(ATTR_MAX_ENTRIES_PER_SECOND,
861           String.valueOf(maxEntriesPerSecond)));
862    }
863
864    return attrList;
865  }
866
867
868
869  /**
870   * {@inheritDoc}
871   */
872  @Override()
873  public List<TaskProperty> getTaskSpecificProperties()
874  {
875    return Collections.unmodifiableList(Arrays.asList(
876         PROPERTY_BACKEND_ID,
877         PROPERTY_INCLUDE_BRANCH,
878         PROPERTY_EXCLUDE_BRANCH,
879         PROPERTY_INCLUDE_FILTER,
880         PROPERTY_EXCLUDE_FILTER,
881         PROPERTY_MAX_ENTRIES_PER_SECOND,
882         PROPERTY_SKIP_FULLY_UNCACHED,
883         PROPERTY_SKIP_PARTIALLY_UNCACHED));
884  }
885
886
887
888  /**
889   * {@inheritDoc}
890   */
891  @Override()
892  public Map<TaskProperty,List<Object>> getTaskPropertyValues()
893  {
894    final LinkedHashMap<TaskProperty,List<Object>> props =
895         new LinkedHashMap<TaskProperty,List<Object>>(15);
896
897    props.put(PROPERTY_BACKEND_ID,
898         Collections.<Object>unmodifiableList(Arrays.asList(backendID)));
899    props.put(PROPERTY_INCLUDE_BRANCH,
900         Collections.<Object>unmodifiableList(includeBranches));
901    props.put(PROPERTY_EXCLUDE_BRANCH,
902         Collections.<Object>unmodifiableList(excludeBranches));
903    props.put(PROPERTY_INCLUDE_FILTER,
904         Collections.<Object>unmodifiableList(includeFilters));
905    props.put(PROPERTY_EXCLUDE_FILTER,
906         Collections.<Object>unmodifiableList(excludeFilters));
907
908    if (maxEntriesPerSecond == null)
909    {
910      props.put(PROPERTY_MAX_ENTRIES_PER_SECOND,
911           Collections.<Object>emptyList());
912    }
913    else
914    {
915      props.put(PROPERTY_MAX_ENTRIES_PER_SECOND,
916           Collections.<Object>unmodifiableList(
917                Arrays.asList(maxEntriesPerSecond)));
918    }
919
920    props.put(PROPERTY_SKIP_FULLY_UNCACHED,
921         Collections.<Object>unmodifiableList(
922              Arrays.asList(skipFullyUncachedEntries)));
923    props.put(PROPERTY_SKIP_PARTIALLY_UNCACHED,
924         Collections.<Object>unmodifiableList(
925              Arrays.asList(skipPartiallyUncachedEntries)));
926
927    props.putAll(super.getTaskPropertyValues());
928    return Collections.unmodifiableMap(props);
929  }
930}