Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.PluginInfrastructure/Advanced/InstallationManagerForm.cs @ 3179

Last change on this file since 3179 was 3179, checked in by gkronber, 14 years ago

Improved controls for deployment service interaction.
Increased max values for message sizes and related limits in the deployment service configuration.
Recreated proxy classes for the deployment service.

#891 (Refactor GUI for plugin management)

File size: 17.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21using System;
22using System.Collections.Generic;
23using System.ComponentModel;
24using System.Data;
25using System.Drawing;
26using System.Linq;
27using System.Text;
28using System.Windows.Forms;
29using System.IO;
30using HeuristicLab.PluginInfrastructure.Manager;
31
32namespace HeuristicLab.PluginInfrastructure.Advanced {
33  internal partial class InstallationManagerForm : Form {
34    private class UpdateOrInstallPluginsBackgroundWorkerArgument {
35      public IEnumerable<IPluginDescription> PluginsToUpdate { get; set; }
36      public IEnumerable<IPluginDescription> PluginsToInstall { get; set; }
37    }
38
39    private class RemovePluginsBackgroundWorkerArgument {
40      public IEnumerable<IPluginDescription> PluginsToRemove { get; set; }
41    }
42
43    private class RefreshBackgroundWorkerResult {
44      public IEnumerable<IPluginDescription> RemotePlugins { get; set; }
45      public IEnumerable<DeploymentService.ProductDescription> RemoteProducts { get; set; }
46    }
47
48    private InstallationManager installationManager;
49    private BackgroundWorker refreshServerPluginsBackgroundWorker;
50    private BackgroundWorker updateOrInstallPluginsBackgroundWorker;
51    private BackgroundWorker removePluginsBackgroundWorker;
52    private BackgroundWorker refreshLocalPluginsBackgroundWorker;
53    private string pluginDir;
54
55    public InstallationManagerForm() {
56      InitializeComponent();
57
58      pluginDir = Application.StartupPath;
59
60      #region initialize background workers
61      refreshServerPluginsBackgroundWorker = new BackgroundWorker();
62      refreshServerPluginsBackgroundWorker.DoWork += new DoWorkEventHandler(refreshServerPluginsBackgroundWorker_DoWork);
63      refreshServerPluginsBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(refreshServerPluginsBackgroundWorker_RunWorkerCompleted);
64
65      updateOrInstallPluginsBackgroundWorker = new BackgroundWorker();
66      updateOrInstallPluginsBackgroundWorker.DoWork += new DoWorkEventHandler(updateOrInstallPluginsBackgroundWorker_DoWork);
67      updateOrInstallPluginsBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(updateOrInstallPluginsBackgroundWorker_RunWorkerCompleted);
68
69      removePluginsBackgroundWorker = new BackgroundWorker();
70      removePluginsBackgroundWorker.DoWork += new DoWorkEventHandler(removePluginsBackgroundWorker_DoWork);
71      removePluginsBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(removePluginsBackgroundWorker_RunWorkerCompleted);
72
73      refreshLocalPluginsBackgroundWorker = new BackgroundWorker();
74      refreshLocalPluginsBackgroundWorker.DoWork += new DoWorkEventHandler(refreshLocalPluginsBackgroundWorker_DoWork);
75      refreshLocalPluginsBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(refreshLocalPluginsBackgroundWorker_RunWorkerCompleted);
76      #endregion
77
78      installationManager = new InstallationManager(pluginDir);
79      installationManager.PluginInstalled += new EventHandler<PluginInfrastructureEventArgs>(installationManager_PluginInstalled);
80      installationManager.PluginRemoved += new EventHandler<PluginInfrastructureEventArgs>(installationManager_PluginRemoved);
81      installationManager.PluginUpdated += new EventHandler<PluginInfrastructureEventArgs>(installationManager_PluginUpdated);
82      installationManager.PreInstallPlugin += new EventHandler<PluginInfrastructureCancelEventArgs>(installationManager_PreInstallPlugin);
83      installationManager.PreRemovePlugin += new EventHandler<PluginInfrastructureCancelEventArgs>(installationManager_PreRemovePlugin);
84      installationManager.PreUpdatePlugin += new EventHandler<PluginInfrastructureCancelEventArgs>(installationManager_PreUpdatePlugin);
85
86      RefreshLocalPluginListAsync();
87    }
88
89    #region event handlers for refresh local plugin list backgroundworker
90    private IEnumerable<PluginDescription> ReloadLocalPlugins() {
91      PluginManager pluginManager = new PluginManager(Application.StartupPath);
92      pluginManager.PluginLoaded += pluginManager_PluginLoaded;
93      pluginManager.PluginUnloaded += pluginManager_PluginUnloaded;
94      pluginManager.Initializing += pluginManager_Initializing;
95      pluginManager.Initialized += pluginManager_Initialized;
96
97      pluginManager.DiscoverAndCheckPlugins();
98
99      pluginManager.PluginLoaded -= pluginManager_PluginLoaded;
100      pluginManager.PluginUnloaded -= pluginManager_PluginUnloaded;
101      pluginManager.Initializing -= pluginManager_Initializing;
102      pluginManager.Initialized -= pluginManager_Initialized;
103
104      return pluginManager.Plugins;
105    }
106    void refreshLocalPluginsBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
107      if (!e.Cancelled && e.Error == null) {
108        UpdateLocalPluginList((IEnumerable<PluginDescription>)e.Result);
109        UpdateControlsConnected();
110      }
111    }
112
113    void refreshLocalPluginsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
114      var plugins = ReloadLocalPlugins();
115      e.Result = plugins;
116    }
117    #endregion
118
119    #region event handlers for plugin removal background worker
120    void removePluginsBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
121      if (!e.Cancelled && e.Error == null) {
122        RefreshLocalPluginListAsync();
123        UpdateControlsConnected();
124      }
125    }
126
127    void removePluginsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
128      IEnumerable<IPluginDescription> pluginsToRemove = (IEnumerable<IPluginDescription>)e.Argument;
129      installationManager.Remove(pluginsToRemove);
130    }
131    #endregion
132
133    #region event handlers for plugin update background worker
134    void updateOrInstallPluginsBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
135      if (!e.Cancelled && e.Error == null) {
136        RefreshLocalPluginListAsync();
137        RefreshRemotePluginListAsync();
138        UpdateControlsConnected();
139      } else {
140        UpdateControlsDisconnected();
141      }
142    }
143
144    void updateOrInstallPluginsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
145      UpdateOrInstallPluginsBackgroundWorkerArgument info = (UpdateOrInstallPluginsBackgroundWorkerArgument)e.Argument;
146      installationManager.Install(info.PluginsToInstall);
147      installationManager.Update(info.PluginsToUpdate);
148    }
149    #endregion
150
151    #region event handlers for refresh server plugins background worker
152    void refreshServerPluginsBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
153      if (!e.Cancelled && e.Result != null) {
154        RefreshBackgroundWorkerResult refreshResult = (RefreshBackgroundWorkerResult)e.Result;
155        UpdateRemotePluginList(refreshResult.RemoteProducts, refreshResult.RemotePlugins);
156        UpdateControlsConnected();
157      } else {
158        UpdateControlsDisconnected();
159      }
160    }
161
162    void refreshServerPluginsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
163      RefreshBackgroundWorkerResult result = new RefreshBackgroundWorkerResult();
164      result.RemotePlugins = installationManager.GetRemotePluginList();
165      result.RemoteProducts = installationManager.GetRemoteProductList();
166      e.Cancel = false;
167      e.Result = result;
168    }
169
170
171
172    #endregion
173
174    #region plugin manager event handlers
175    void pluginManager_Initialized(object sender, PluginInfrastructureEventArgs e) {
176      SetStatusStrip("Initialized PluginInfrastructure");
177    }
178
179    void pluginManager_Initializing(object sender, PluginInfrastructureEventArgs e) {
180      SetStatusStrip("Initializing PluginInfrastructure");
181    }
182
183    void pluginManager_PluginUnloaded(object sender, PluginInfrastructureEventArgs e) {
184      SetStatusStrip("Unloaded " + e.Entity);
185    }
186
187    void pluginManager_PluginLoaded(object sender, PluginInfrastructureEventArgs e) {
188      SetStatusStrip("Loaded " + e.Entity);
189    }
190    #endregion
191
192    #region installation manager event handlers
193    void installationManager_PreUpdatePlugin(object sender, PluginInfrastructureCancelEventArgs e) {
194      if (e.Plugins.Count() > 0) {
195        e.Cancel = ConfirmUpdateAction(e.Plugins) == false;
196      }
197    }
198
199    void installationManager_PreRemovePlugin(object sender, PluginInfrastructureCancelEventArgs e) {
200      if (e.Plugins.Count() > 0) {
201        e.Cancel = ConfirmRemoveAction(e.Plugins) == false;
202      }
203    }
204
205    void installationManager_PreInstallPlugin(object sender, PluginInfrastructureCancelEventArgs e) {
206      if (e.Plugins.Count() > 0)
207        if (ConfirmInstallAction(e.Plugins) == true) {
208          SetStatusStrip("Installing " + e.Plugins.Aggregate("", (a, b) => a.ToString() + "; " + b.ToString()));
209          e.Cancel = false;
210        } else {
211          e.Cancel = true;
212          SetStatusStrip("Install canceled");
213        }
214    }
215
216    void installationManager_PluginUpdated(object sender, PluginInfrastructureEventArgs e) {
217      SetStatusStrip("Updated " + e.Entity);
218    }
219
220    void installationManager_PluginRemoved(object sender, PluginInfrastructureEventArgs e) {
221      SetStatusStrip("Removed " + e.Entity);
222    }
223
224    void installationManager_PluginInstalled(object sender, PluginInfrastructureEventArgs e) {
225      SetStatusStrip("Installed " + e.Entity);
226    }
227    #endregion
228
229    private void SetStatusStrip(string msg) {
230      if (InvokeRequired) Invoke((Action<string>)SetStatusStrip, msg);
231      else {
232        toolStripStatusLabel.Text = msg;
233        logTextBox.Text += DateTime.Now + ": " + msg + Environment.NewLine;
234      }
235    }
236
237    #region button events
238
239    private void refreshButton_Click(object sender, EventArgs e) {
240      RefreshRemotePluginListAsync();
241    }
242
243    private void updateButton_Click(object sender, EventArgs e) {
244      Cursor = Cursors.AppStarting;
245      toolStripProgressBar.Visible = true;
246      DisableControls();
247      var updateOrInstallInfo = new UpdateOrInstallPluginsBackgroundWorkerArgument();
248      // if there is a local plugin with same name and same major and minor version then it's an update
249      var pluginsToUpdate = from remotePlugin in remotePluginInstaller.CheckedPlugins
250                            let matchingLocalPlugins = from localPlugin in localPluginManager.Plugins
251                                                       where localPlugin.Name == remotePlugin.Name
252                                                       where localPlugin.Version.Major == remotePlugin.Version.Major
253                                                       where localPlugin.Version.Minor == remotePlugin.Version.Minor
254                                                       select localPlugin
255                            where matchingLocalPlugins.Count() > 0
256                            select remotePlugin;
257
258      // otherwise install a new plugin
259      var pluginsToInstall = remotePluginInstaller.CheckedPlugins.Except(pluginsToUpdate);
260
261      updateOrInstallInfo.PluginsToInstall = pluginsToInstall;
262      updateOrInstallInfo.PluginsToUpdate = pluginsToUpdate;
263      updateOrInstallPluginsBackgroundWorker.RunWorkerAsync(updateOrInstallInfo);
264    }
265
266    private void removeButton_Click(object sender, EventArgs e) {
267      Cursor = Cursors.AppStarting;
268      toolStripProgressBar.Visible = true;
269      DisableControls();
270      removePluginsBackgroundWorker.RunWorkerAsync(localPluginManager.CheckedPlugins);
271    }
272
273    #endregion
274
275    #region confirmation dialogs
276    private bool ConfirmRemoveAction(IEnumerable<IPluginDescription> plugins) {
277      StringBuilder strBuilder = new StringBuilder();
278      foreach (var plugin in plugins) {
279        foreach (var file in plugin.Files) {
280          strBuilder.AppendLine(Path.GetFileName(file.Name));
281        }
282      }
283      return (new ConfirmationDialog("Confirm Delete", "Do you want to delete following files?", strBuilder.ToString())).ShowDialog() == DialogResult.OK;
284    }
285
286    private bool ConfirmUpdateAction(IEnumerable<IPluginDescription> plugins) {
287      StringBuilder strBuilder = new StringBuilder();
288      foreach (var plugin in plugins) {
289        strBuilder.AppendLine(plugin.ToString());
290      }
291      return (new ConfirmationDialog("Confirm Update", "Do you want to update following plugins?", strBuilder.ToString())).ShowDialog() == DialogResult.OK;
292    }
293
294    private bool ConfirmInstallAction(IEnumerable<IPluginDescription> plugins) {
295      foreach (var plugin in plugins) {
296        if (!string.IsNullOrEmpty(plugin.LicenseText)) {
297          var licenseConfirmationBox = new LicenseConfirmationBox(plugin);
298          if (licenseConfirmationBox.ShowDialog() != DialogResult.OK)
299            return false;
300        }
301      }
302      return true;
303    }
304
305
306    #endregion
307
308    #region helper methods
309
310    private void UpdateLocalPluginList(IEnumerable<PluginDescription> plugins) {
311      localPluginManager.Plugins = plugins;
312    }
313
314    private void UpdateRemotePluginList(
315      IEnumerable<DeploymentService.ProductDescription> remoteProducts,
316      IEnumerable<IPluginDescription> remotePlugins) {
317
318      var mostRecentRemotePlugins = from remote in remotePlugins
319                                    where !remotePlugins.Any(x => x.Name == remote.Name && x.Version > remote.Version) // same name and higher version
320                                    select remote;
321
322      var newPlugins = from remote in mostRecentRemotePlugins
323                       let matchingLocal = (from local in localPluginManager.Plugins
324                                            where local.Name == remote.Name
325                                            where local.Version < remote.Version
326                                            select local).FirstOrDefault()
327                       where matchingLocal != null
328                       select remote;
329
330      remotePluginInstaller.NewPlugins = newPlugins;
331      remotePluginInstaller.Products = remoteProducts;
332      remotePluginInstaller.AllPlugins = remotePlugins;
333    }
334
335    private void RefreshRemotePluginListAsync() {
336      Cursor = Cursors.AppStarting;
337      toolStripProgressBar.Visible = true;
338      refreshButton.Enabled = false;
339      refreshServerPluginsBackgroundWorker.RunWorkerAsync();
340    }
341
342    private void RefreshLocalPluginListAsync() {
343      Cursor = Cursors.AppStarting;
344      toolStripProgressBar.Visible = true;
345      DisableControls();
346      refreshLocalPluginsBackgroundWorker.RunWorkerAsync();
347    }
348
349    private void UpdateControlsDisconnected() {
350      //localPluginsListView.Enabled = false;
351      //ClearPluginsList(remotePluginsListView);
352      refreshButton.Enabled = true;
353      toolStripProgressBar.Visible = false;
354      Cursor = Cursors.Default;
355    }
356
357    private void UpdateControlsConnected() {
358      refreshButton.Enabled = true;
359      toolStripProgressBar.Visible = false;
360      Cursor = Cursors.Default;
361    }
362
363    private void DisableControls() {
364      refreshButton.Enabled = false;
365      Cursor = Cursors.Default;
366    }
367    #endregion
368
369    private void localPluginManager_ItemChecked(object sender, ItemCheckedEventArgs e) {
370      removeButton.Enabled = localPluginManager.CheckedPlugins.Count() > 0;
371    }
372
373    private void remotePluginInstaller_ItemChecked(object sender, ItemCheckedEventArgs e) {
374      installButton.Enabled = remotePluginInstaller.CheckedPlugins.Count() > 0;
375    }
376
377    private void editConnectionButton_Click(object sender, EventArgs e) {
378      (new ConnectionSetupView()).ShowInForm();
379    }
380
381    protected override void OnClosing(CancelEventArgs e) {
382      installationManager.PluginInstalled -= new EventHandler<PluginInfrastructureEventArgs>(installationManager_PluginInstalled);
383      installationManager.PluginRemoved -= new EventHandler<PluginInfrastructureEventArgs>(installationManager_PluginRemoved);
384      installationManager.PluginUpdated -= new EventHandler<PluginInfrastructureEventArgs>(installationManager_PluginUpdated);
385      installationManager.PreInstallPlugin -= new EventHandler<PluginInfrastructureCancelEventArgs>(installationManager_PreInstallPlugin);
386      installationManager.PreRemovePlugin -= new EventHandler<PluginInfrastructureCancelEventArgs>(installationManager_PreRemovePlugin);
387      installationManager.PreUpdatePlugin -= new EventHandler<PluginInfrastructureCancelEventArgs>(installationManager_PreUpdatePlugin);
388      base.OnClosing(e);
389    }
390  }
391}
Note: See TracBrowser for help on using the repository browser.