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