001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2010 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2016 ForgeRock AS.
016 */
017package org.opends.server.tools.tasks;
018
019import java.util.ArrayList;
020import java.util.Collection;
021import java.util.Collections;
022import java.util.Date;
023import java.util.List;
024
025import org.opends.server.admin.client.cli.TaskScheduleArgs;
026import org.opends.server.backends.task.FailedDependencyAction;
027import org.opends.server.util.StaticUtils;
028import com.forgerock.opendj.cli.ArgumentException;
029import com.forgerock.opendj.cli.StringArgument;
030import com.forgerock.opendj.cli.CommandBuilder;
031
032/**
033 * A generic data structure that contains the data that the user provided to
034 * schedule a task.
035 * <br>
036 * The main difference with {@link TaskScheduleInformation} is that this class
037 * is completely agnostic of the execution.
038 */
039public class TaskScheduleUserData
040{
041  private boolean startNow;
042  private Date startDate;
043  private String recurringDateTime;
044  private final List<String> dependencyIds = new ArrayList<>();
045  private FailedDependencyAction failedDependencyAction;
046  private final List<String> notifyUponCompletionEmailAddresses = new ArrayList<>();
047  private final List<String> notifyUponErrorEmailAddresses = new ArrayList<>();
048
049  /**
050   * Whether the arguments provided by the user, indicate that the task should
051   * be executed immediately.
052   * @return {@code true} if the task must be executed immediately and
053   * {@code false} otherwise.
054   */
055  public boolean isStartNow()
056  {
057    return startNow;
058  }
059
060  /**
061   * Sets whether the arguments provided by the user, indicate that the task
062   * should be executed immediately.
063   * @param startNow {@code true} if the task must be executed immediately and
064   * {@code false} otherwise.
065   */
066  public void setStartNow(boolean startNow)
067  {
068    this.startNow = startNow;
069  }
070
071  /**
072   * Gets the date at which this task should be scheduled to start.
073   *
074   * @return date/time at which the task should be scheduled
075   */
076  public Date getStartDate()
077  {
078    return startDate;
079  }
080
081  /**
082   * Sets the date at which this task should be scheduled to start.
083   *
084   * @param startDate the date/time at which the task should be scheduled
085   */
086  public void setStartDate(Date startDate)
087  {
088    this.startDate = startDate;
089  }
090
091  /**
092   * Gets the date/time pattern for recurring task schedule.
093   *
094   * @return recurring date/time pattern at which the task
095   *         should be scheduled.
096   */
097  public String getRecurringDateTime()
098  {
099    return recurringDateTime;
100  }
101
102  /**
103   * Sets the date/time pattern for recurring task schedule.
104   *
105   * @param recurringDateTime recurring date/time pattern at which the task
106   *         should be scheduled.
107   */
108  public void setRecurringDateTime(String recurringDateTime)
109  {
110    this.recurringDateTime = recurringDateTime;
111  }
112
113  /**
114   * Gets a list of task IDs upon which this task is dependent.
115   *
116   * @return list of task IDs
117   */
118  public List<String> getDependencyIds()
119  {
120    return dependencyIds;
121  }
122
123  /**
124   * Sets the list of task IDs upon which this task is dependent.
125   *
126   * @param dependencyIds list of task IDs
127   */
128  public void setDependencyIds(List<String> dependencyIds)
129  {
130    this.dependencyIds.clear();
131    this.dependencyIds.addAll(dependencyIds);
132  }
133
134  /**
135   * Gets the action to take should one of the dependent task fail.
136   *
137   * @return action to take
138   */
139  public FailedDependencyAction getFailedDependencyAction()
140  {
141    return failedDependencyAction;
142  }
143
144  /**
145   * Sets the action to take should one of the dependent task fail.
146   *
147   * @param failedDependencyAction the action to take
148   */
149  public void setFailedDependencyAction(
150      FailedDependencyAction failedDependencyAction)
151  {
152    this.failedDependencyAction = failedDependencyAction;
153  }
154
155  /**
156   * Gets a list of email address to which an email will be sent when this
157   * task completes.
158   *
159   * @return list of email addresses
160   */
161  public List<String> getNotifyUponCompletionEmailAddresses()
162  {
163    return notifyUponCompletionEmailAddresses;
164  }
165
166  /**
167   * Sets the list of email address to which an email will be sent when this
168   * task completes.
169   *
170   * @param notifyUponCompletionEmailAddresses the list of email addresses
171   */
172  public void setNotifyUponCompletionEmailAddresses(
173      List<String> notifyUponCompletionEmailAddresses)
174  {
175    this.notifyUponCompletionEmailAddresses.clear();
176    this.notifyUponCompletionEmailAddresses.addAll(
177        notifyUponCompletionEmailAddresses);
178  }
179
180  /**
181   * Gets the list of email address to which an email will be sent if this
182   * task encounters an error during execution.
183   *
184   * @return list of email addresses
185   */
186  public List<String> getNotifyUponErrorEmailAddresses()
187  {
188    return notifyUponErrorEmailAddresses;
189  }
190
191  /**
192   * Sets the list of email address to which an email will be sent if this
193   * task encounters an error during execution.
194   *
195   * @param notifyUponErrorEmailAddresses the list of email addresses
196   */
197  public void setNotifyUponErrorEmailAddresses(
198      List<String> notifyUponErrorEmailAddresses)
199  {
200    this.notifyUponErrorEmailAddresses.clear();
201    this.notifyUponErrorEmailAddresses.addAll(notifyUponErrorEmailAddresses);
202  }
203
204
205  /**
206   * An static utility method that can be used to update the object used to
207   * display the equivalent command-line with the contents of a given
208   * task schedule object.
209   * @param commandBuilder the command builder.
210   * @param taskSchedule the task schedule.
211   */
212  public static void updateCommandBuilderWithTaskSchedule(
213      CommandBuilder commandBuilder,
214      TaskScheduleUserData taskSchedule)
215  {
216    TaskScheduleArgs argsToClone = new TaskScheduleArgs();
217    String sDate = null;
218    String recurringDateTime = null;
219    if (!taskSchedule.isStartNow())
220    {
221      Date date = taskSchedule.getStartDate();
222      if (date != null)
223      {
224        sDate = StaticUtils.formatDateTimeString(date);
225      }
226      recurringDateTime = taskSchedule.getRecurringDateTime();
227    }
228
229    String sFailedDependencyAction = null;
230    FailedDependencyAction fAction = taskSchedule.getFailedDependencyAction();
231    if (fAction != null)
232    {
233      sFailedDependencyAction = fAction.name();
234    }
235    String[] sValues = {sDate, recurringDateTime, sFailedDependencyAction};
236    StringArgument[] args = {argsToClone.startArg,
237        argsToClone.recurringArg, argsToClone.failedDependencyActionArg};
238    for (int i=0; i<sValues.length; i++)
239    {
240      if (sValues[i] != null)
241      {
242        commandBuilder.addArgument(getArgument(args[i],
243            Collections.singleton(sValues[i])));
244      }
245    }
246
247    List<?>[] values = {taskSchedule.getDependencyIds(),
248        taskSchedule.getNotifyUponCompletionEmailAddresses(),
249        taskSchedule.getNotifyUponErrorEmailAddresses()};
250    args = new StringArgument[]{argsToClone.dependencyArg,
251        argsToClone.completionNotificationArg,
252        argsToClone.errorNotificationArg};
253
254    for (int i=0; i<values.length; i++)
255    {
256      if (!values[i].isEmpty())
257      {
258        commandBuilder.addArgument(getArgument(args[i],
259            values[i]));
260      }
261    }
262  }
263
264  private static StringArgument getArgument(StringArgument argToClone, Collection<?> values)
265  {
266    StringArgument arg;
267    try
268    {
269      StringArgument.Builder argBuilder =
270              StringArgument.builder(argToClone.getLongIdentifier())
271                      .shortIdentifier(argToClone.getShortIdentifier())
272                      .description(argToClone.getDescription())
273                      .defaultValue(argToClone.getDefaultValue())
274                      .valuePlaceholder(argToClone.getValuePlaceholder());
275      if (argToClone.isRequired()) {
276        argBuilder.required();
277      }
278      if (argToClone.isMultiValued()) {
279        argBuilder.multiValued();
280      }
281      arg = argBuilder.buildArgument();
282    }
283    catch (ArgumentException e)
284    {
285      // This is a bug.
286      throw new RuntimeException("Unexpected error: "+e, e);
287    }
288    for (Object v : values)
289    {
290      arg.addValue(String.valueOf(v));
291    }
292    return arg;
293  }
294}