001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027
028package org.opends.guitools.controlpanel.task;
029
030import static org.opends.messages.AdminToolMessages.*;
031
032import java.util.ArrayList;
033import java.util.Collection;
034import java.util.HashSet;
035import java.util.List;
036import java.util.Set;
037import java.util.TreeSet;
038
039import javax.swing.SwingUtilities;
040
041import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
042import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
043import org.opends.guitools.controlpanel.ui.ProgressDialog;
044import org.forgerock.i18n.LocalizableMessage;
045import org.opends.server.tools.ManageTasks;
046import org.opends.server.tools.tasks.TaskEntry;
047
048/**
049 * Task used to cancel tasks in server.
050 *
051 */
052public class CancelTaskTask extends Task
053{
054  private Set<String> backendSet;
055  private List<TaskEntry> tasks;
056
057  /**
058   * Constructor of the task.
059   * @param info the control panel information.
060   * @param dlg the progress dialog where the task progress will be displayed.
061   * @param tasks the tasks to be canceled.
062   */
063  public CancelTaskTask(ControlPanelInfo info, ProgressDialog dlg,
064      List<TaskEntry> tasks)
065  {
066    super(info, dlg);
067    backendSet = new HashSet<>();
068    for (BackendDescriptor backend : info.getServerDescriptor().getBackends())
069    {
070      backendSet.add(backend.getBackendID());
071    }
072    this.tasks = new ArrayList<>(tasks);
073  }
074
075  /** {@inheritDoc} */
076  public Type getType()
077  {
078    // TODO: change this
079    return Type.MODIFY_ENTRY;
080  }
081
082  /** {@inheritDoc} */
083  public Set<String> getBackends()
084  {
085    return backendSet;
086  }
087
088  /** {@inheritDoc} */
089  public LocalizableMessage getTaskDescription()
090  {
091    return INFO_CTRL_PANEL_CANCEL_TASK_DESCRIPTION.get();
092  }
093
094  /** {@inheritDoc} */
095  public boolean regenerateDescriptor()
096  {
097    return true;
098  }
099
100  /** {@inheritDoc} */
101  protected String getCommandLinePath()
102  {
103    return null;
104  }
105
106  /** {@inheritDoc} */
107  protected ArrayList<String> getCommandLineArguments()
108  {
109    return new ArrayList<>();
110  }
111
112  /**
113   * Returns the command-line arguments to be used to cancel the task.
114   * @param task the task to be canceled.
115   * @return the command-line arguments to be used to cancel the task.
116   */
117  private ArrayList<String> getCommandLineArguments(TaskEntry task)
118  {
119    ArrayList<String> args = new ArrayList<>();
120    args.add("--cancel");
121    args.add(task.getId());
122    args.addAll(getConnectionCommandLineArguments());
123    args.add(getNoPropertiesFileArgument());
124    return args;
125  }
126
127  /** {@inheritDoc} */
128  public boolean canLaunch(Task taskToBeLaunched,
129      Collection<LocalizableMessage> incompatibilityReasons)
130  {
131    if (!isServerRunning() && state == State.RUNNING)
132    {
133      // All the operations are incompatible if they apply to this
134      // backend for safety.  This is a short operation so the limitation
135      // has not a lot of impact.
136      Set<String> backends = new TreeSet<>(taskToBeLaunched.getBackends());
137      backends.retainAll(getBackends());
138      if (!backends.isEmpty())
139      {
140        incompatibilityReasons.add(getIncompatibilityMessage(this, taskToBeLaunched));
141        return false;
142      }
143    }
144    return true;
145  }
146
147  /** {@inheritDoc} */
148  public void runTask()
149  {
150    state = State.RUNNING;
151    lastException = null;
152    try
153    {
154      final int totalNumber = tasks.size();
155      int numberCanceled = 0;
156
157      SwingUtilities.invokeLater(new Runnable()
158      {
159        public void run()
160        {
161          getProgressDialog().getProgressBar().setIndeterminate(true);
162        }
163      });
164      for (final TaskEntry task : tasks)
165      {
166        final ArrayList<String> arguments = getCommandLineArguments(task);
167
168        final boolean isFirst = numberCanceled == 0;
169        SwingUtilities.invokeLater(new Runnable()
170        {
171          public void run()
172          {
173            if (isFirst)
174            {
175              getProgressDialog().appendProgressHtml("<br><br>");
176            }
177            ArrayList<String> args = new ArrayList<>(getObfuscatedCommandLineArguments(arguments));
178            printEquivalentCommandLine(getCommandLinePath("manage-tasks"),
179                    args, INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_CANCEL_TASK.get(
180                        task.getId()));
181          }
182        });
183
184        String[] args = new String[arguments.size()];
185
186        arguments.toArray(args);
187
188        returnCode = ManageTasks.mainTaskInfo(args, System.in,
189            outPrintStream, errorPrintStream, false);
190        if (returnCode != 0)
191        {
192          break;
193        }
194        else
195        {
196          numberCanceled ++;
197          final int fNumberCanceled = numberCanceled;
198          SwingUtilities.invokeLater(new Runnable()
199          {
200            public void run()
201            {
202              if (fNumberCanceled == 1)
203              {
204                getProgressDialog().getProgressBar().setIndeterminate(false);
205              }
206              getProgressDialog().getProgressBar().setValue(
207                  (fNumberCanceled * 100) / totalNumber);
208            }
209          });
210        }
211      }
212      if (returnCode != 0)
213      {
214        state = State.FINISHED_WITH_ERROR;
215      }
216      else
217      {
218        state = State.FINISHED_SUCCESSFULLY;
219      }
220    }
221    catch (Throwable t)
222    {
223      lastException = t;
224      state = State.FINISHED_WITH_ERROR;
225    }
226  }
227}