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 2009 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2016 ForgeRock AS.
016 */
017package org.opends.guitools.controlpanel.task;
018
019import static org.opends.messages.AdminToolMessages.*;
020
021import java.util.ArrayList;
022import java.util.Collection;
023import java.util.HashSet;
024import java.util.List;
025import java.util.Set;
026import java.util.TreeSet;
027
028import javax.swing.JProgressBar;
029import javax.swing.SwingUtilities;
030
031import org.forgerock.i18n.LocalizableMessage;
032import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
033import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
034import org.opends.guitools.controlpanel.ui.ProgressDialog;
035import org.opends.server.tools.ManageTasks;
036import org.opends.server.tools.tasks.TaskEntry;
037
038/** Task used to cancel tasks in server. */
039public class CancelTaskTask extends Task
040{
041  private Set<String> backendSet;
042  private List<TaskEntry> tasks;
043
044  /**
045   * Constructor of the task.
046   * @param info the control panel information.
047   * @param dlg the progress dialog where the task progress will be displayed.
048   * @param tasks the tasks to be canceled.
049   */
050  public CancelTaskTask(ControlPanelInfo info, ProgressDialog dlg,
051      List<TaskEntry> tasks)
052  {
053    super(info, dlg);
054    backendSet = new HashSet<>();
055    for (BackendDescriptor backend : info.getServerDescriptor().getBackends())
056    {
057      backendSet.add(backend.getBackendID());
058    }
059    this.tasks = new ArrayList<>(tasks);
060  }
061
062  @Override
063  public Type getType()
064  {
065    // TODO: change this
066    return Type.MODIFY_ENTRY;
067  }
068
069  @Override
070  public Set<String> getBackends()
071  {
072    return backendSet;
073  }
074
075  @Override
076  public LocalizableMessage getTaskDescription()
077  {
078    return INFO_CTRL_PANEL_CANCEL_TASK_DESCRIPTION.get();
079  }
080
081  @Override
082  public boolean regenerateDescriptor()
083  {
084    return true;
085  }
086
087  @Override
088  protected String getCommandLinePath()
089  {
090    return null;
091  }
092
093  @Override
094  protected ArrayList<String> getCommandLineArguments()
095  {
096    return new ArrayList<>();
097  }
098
099  /**
100   * Returns the command-line arguments to be used to cancel the task.
101   * @param task the task to be canceled.
102   * @return the command-line arguments to be used to cancel the task.
103   */
104  private ArrayList<String> getCommandLineArguments(TaskEntry task)
105  {
106    ArrayList<String> args = new ArrayList<>();
107    args.add("--cancel");
108    args.add(task.getId());
109    args.addAll(getConnectionCommandLineArguments());
110    args.add(getNoPropertiesFileArgument());
111    return args;
112  }
113
114  @Override
115  public boolean canLaunch(Task taskToBeLaunched,
116      Collection<LocalizableMessage> incompatibilityReasons)
117  {
118    if (!isServerRunning() && state == State.RUNNING)
119    {
120      // All the operations are incompatible if they apply to this
121      // backend for safety.  This is a short operation so the limitation
122      // has not a lot of impact.
123      Set<String> backends = new TreeSet<>(taskToBeLaunched.getBackends());
124      backends.retainAll(getBackends());
125      if (!backends.isEmpty())
126      {
127        incompatibilityReasons.add(getIncompatibilityMessage(this, taskToBeLaunched));
128        return false;
129      }
130    }
131    return true;
132  }
133
134  @Override
135  public void runTask()
136  {
137    state = State.RUNNING;
138    lastException = null;
139    try
140    {
141      final int totalNumber = tasks.size();
142      int numberCanceled = 0;
143
144      SwingUtilities.invokeLater(new Runnable()
145      {
146        @Override
147        public void run()
148        {
149          getProgressDialog().getProgressBar().setIndeterminate(true);
150        }
151      });
152      for (final TaskEntry task : tasks)
153      {
154        final ArrayList<String> arguments = getCommandLineArguments(task);
155
156        final boolean isFirst = numberCanceled == 0;
157        SwingUtilities.invokeLater(new Runnable()
158        {
159          @Override
160          public void run()
161          {
162            if (isFirst)
163            {
164              getProgressDialog().appendProgressHtml("<br><br>");
165            }
166            ArrayList<String> args = new ArrayList<>(getObfuscatedCommandLineArguments(arguments));
167            printEquivalentCommandLine(getCommandLinePath("manage-tasks"),
168                    args, INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_CANCEL_TASK.get(
169                        task.getId()));
170          }
171        });
172
173        String[] args = new String[arguments.size()];
174
175        arguments.toArray(args);
176
177        returnCode = ManageTasks.mainTaskInfo(args, outPrintStream, errorPrintStream, false);
178        if (returnCode != 0)
179        {
180          break;
181        }
182
183        numberCanceled++;
184        final int fNumberCanceled = numberCanceled;
185        SwingUtilities.invokeLater(new Runnable()
186        {
187          @Override
188          public void run()
189          {
190            JProgressBar progressBar = getProgressDialog().getProgressBar();
191            if (fNumberCanceled == 1)
192            {
193              progressBar.setIndeterminate(false);
194            }
195            progressBar.setValue((fNumberCanceled * 100) / totalNumber);
196          }
197        });
198      }
199      if (returnCode != 0)
200      {
201        state = State.FINISHED_WITH_ERROR;
202      }
203      else
204      {
205        state = State.FINISHED_SUCCESSFULLY;
206      }
207    }
208    catch (Throwable t)
209    {
210      lastException = t;
211      state = State.FINISHED_WITH_ERROR;
212    }
213  }
214}