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