Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.PluginInfrastructure/3.3/Advanced/UploadPluginsView.cs @ 16755

Last change on this file since 16755 was 16565, checked in by gkronber, 6 years ago

#2520: merged changes from PersistenceOverhaul branch (r16451:16564) into trunk

File size: 12.0 KB
RevLine 
[3081]1#region License Information
2/* HeuristicLab
[16565]3 * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[3081]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
21
22using System;
[2802]23using System.Collections.Generic;
24using System.ComponentModel;
25using System.Drawing;
[4068]26using System.IO;
[11650]27using System.IO.Compression;
[2802]28using System.Linq;
[4068]29using System.ServiceModel;
[2802]30using System.Windows.Forms;
[4068]31using HeuristicLab.PluginInfrastructure.Manager;
[2802]32
[3474]33namespace HeuristicLab.PluginInfrastructure.Advanced {
[3627]34  internal partial class UploadPluginsView : InstallationManagerControl {
[3612]35    private const string UploadMessage = "Uploading plugins...";
36    private const string RefreshMessage = "Downloading plugin information from deployment service...";
37
[3509]38    private Dictionary<IPluginDescription, IPluginDescription> localAndServerPlugins;
[2802]39    private BackgroundWorker pluginUploadWorker;
[3612]40    private BackgroundWorker refreshPluginsWorker;
[2802]41
[3547]42    private PluginManager pluginManager;
43    public PluginManager PluginManager {
44      get { return pluginManager; }
[3608]45      set { pluginManager = value; }
[3547]46    }
47
[3627]48    public UploadPluginsView() {
[2802]49      InitializeComponent();
[3721]50      pluginImageList.Images.Add(HeuristicLab.PluginInfrastructure.Resources.Plugin);
[3509]51      localAndServerPlugins = new Dictionary<IPluginDescription, IPluginDescription>();
[2816]52
[2860]53      #region initialize backgroundworkers
[2802]54      pluginUploadWorker = new BackgroundWorker();
55      pluginUploadWorker.DoWork += new DoWorkEventHandler(pluginUploadWorker_DoWork);
56      pluginUploadWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(pluginUploadWorker_RunWorkerCompleted);
57
[3612]58      refreshPluginsWorker = new BackgroundWorker();
59      refreshPluginsWorker.DoWork += new DoWorkEventHandler(refreshPluginsWorker_DoWork);
60      refreshPluginsWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(refreshPluginsWorker_RunWorkerCompleted);
[2860]61      #endregion
[2802]62    }
63
[2860]64    #region refresh plugins from server backgroundworker
[3612]65    void refreshPluginsWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
[3547]66      if (e.Error != null) {
[3612]67        StatusView.ShowError("Connection Error",
68          "There was an error while connecting to the server." + Environment.NewLine +
[3547]69                   "Please check your connection settings and user credentials.");
70      } else {
[3612]71        UpdatePluginListView((IEnumerable<IPluginDescription>)e.Result);
[2816]72      }
[3612]73      StatusView.HideProgressIndicator();
74      StatusView.RemoveMessage(RefreshMessage);
75      StatusView.UnlockUI();
[2816]76    }
77
[3612]78    void refreshPluginsWorker_DoWork(object sender, DoWorkEventArgs e) {
79      // refresh available plugins
[4495]80      var client = DeploymentService.UpdateServiceClientFactory.CreateClient();
[3612]81      try {
82        e.Result = client.GetPlugins();
83        client.Close();
84      }
85      catch (TimeoutException) {
86        client.Abort();
87        throw;
88      }
89      catch (FaultException) {
90        client.Abort();
91        throw;
92      }
93      catch (CommunicationException) {
94        client.Abort();
95        throw;
96      }
[2816]97    }
[2860]98    #endregion
[2816]99
[2860]100    #region upload plugins to server backgroundworker
[2802]101    void pluginUploadWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
[3547]102      if (e.Error != null) {
[3612]103        StatusView.ShowError("Connection Error",
104          "There was an error while connecting to the server." + Environment.NewLine +
[3547]105                   "Please check your connection settings and user credentials.");
[2860]106      } else {
[3612]107        UpdatePluginListView((IEnumerable<IPluginDescription>)e.Result);
[2860]108      }
[3612]109      StatusView.RemoveMessage(UploadMessage);
110      StatusView.HideProgressIndicator();
111      StatusView.UnlockUI();
[2802]112    }
113
114    void pluginUploadWorker_DoWork(object sender, DoWorkEventArgs e) {
[3612]115      // upload plugins
[3547]116      var selectedPlugins = (IEnumerable<IPluginDescription>)e.Argument;
[4495]117      DeploymentService.AdminServiceClient adminClient = DeploymentService.AdminServiceClientFactory.CreateClient();
[3710]118      Dictionary<IPluginDescription, DeploymentService.PluginDescription> cachedPluginDescriptions =
119        new Dictionary<IPluginDescription, DeploymentService.PluginDescription>();
[3612]120      try {
121        foreach (var plugin in IteratePlugins(selectedPlugins)) {
[3710]122          adminClient.DeployPlugin(MakePluginDescription(plugin, cachedPluginDescriptions), CreateZipPackage(plugin));
[3612]123        }
124        adminClient.Close();
[2802]125      }
[3612]126      catch (TimeoutException) {
127        adminClient.Abort();
128        throw;
129      }
130      catch (FaultException) {
131        adminClient.Abort();
132        throw;
133      }
134      catch (CommunicationException) {
135        adminClient.Abort();
136        throw;
137      }
138      // refresh available plugins
[4495]139      var client = DeploymentService.UpdateServiceClientFactory.CreateClient();
[3612]140      try {
141        e.Result = client.GetPlugins();
142        client.Close();
143      }
144      catch (TimeoutException) {
145        client.Abort();
146        throw;
147      }
148      catch (FaultException) {
149        client.Abort();
150        throw;
151      }
152      catch (CommunicationException) {
153        client.Abort();
154        throw;
155      }
[2802]156    }
[2860]157    #endregion
[2802]158
[2860]159
160    #region button events
161    private void uploadButton_Click(object sender, EventArgs e) {
162      var selectedPlugins = from item in listView.Items.Cast<ListViewItem>()
163                            where item.Checked
164                            where item.Tag is IPluginDescription
165                            select item.Tag as IPluginDescription;
166      if (selectedPlugins.Count() > 0) {
[3612]167        StatusView.LockUI();
168        StatusView.ShowProgressIndicator();
169        StatusView.ShowMessage(UploadMessage);
[2860]170        pluginUploadWorker.RunWorkerAsync(selectedPlugins.ToList());
171      }
172    }
173
174    private void refreshButton_Click(object sender, EventArgs e) {
[3612]175      StatusView.LockUI();
176      StatusView.ShowProgressIndicator();
177      StatusView.ShowMessage(RefreshMessage);
178      refreshPluginsWorker.RunWorkerAsync();
[2860]179    }
180
181    #endregion
182
183    #region item list events
[3612]184    private bool ignoreItemCheckedEvents = false;
[3068]185    private void listView_ItemChecked(object sender, ItemCheckedEventArgs e) {
[3612]186      if (ignoreItemCheckedEvents) return;
[3068]187      List<IPluginDescription> modifiedPlugins = new List<IPluginDescription>();
[2860]188      if (e.Item.Checked) {
[3068]189        foreach (ListViewItem item in listView.SelectedItems) {
190          var plugin = (IPluginDescription)item.Tag;
191          // also check all dependencies
[3179]192          if (!modifiedPlugins.Contains(plugin))
193            modifiedPlugins.Add(plugin);
[3627]194          foreach (var dep in Util.GetAllDependencies(plugin)) {
[3179]195            if (!modifiedPlugins.Contains(dep))
196              modifiedPlugins.Add(dep);
[3068]197          }
[2860]198        }
[3068]199        listView.CheckItems(modifiedPlugins.Select(x => FindItemForPlugin(x)));
[2860]200      } else {
[3068]201        foreach (ListViewItem item in listView.SelectedItems) {
202          var plugin = (IPluginDescription)item.Tag;
203          // also uncheck all dependent plugins
[3179]204          if (!modifiedPlugins.Contains(plugin))
205            modifiedPlugins.Add(plugin);
[3627]206          foreach (var dep in Util.GetAllDependents(plugin, localAndServerPlugins.Keys)) {
[3179]207            if (!modifiedPlugins.Contains(dep))
208              modifiedPlugins.Add(dep);
[2860]209          }
210        }
[3068]211        listView.UncheckItems(modifiedPlugins.Select(x => FindItemForPlugin(x)));
[2860]212      }
[3068]213      uploadButton.Enabled = (from i in listView.Items.OfType<ListViewItem>()
214                              where i.Checked
215                              select i).Any();
[2860]216    }
217    #endregion
218
219    #region helper methods
[3612]220    private void UpdatePluginListView(IEnumerable<IPluginDescription> remotePlugins) {
221      // refresh local plugins
222      localAndServerPlugins.Clear();
223      foreach (var plugin in pluginManager.Plugins) {
224        localAndServerPlugins.Add(plugin, null);
225      }
226      foreach (var plugin in remotePlugins) {
227        var matchingLocalPlugin = (from localPlugin in localAndServerPlugins.Keys
228                                   where localPlugin.Name == plugin.Name
[3710]229                                   where localPlugin.Version == plugin.Version
[3612]230                                   select localPlugin).SingleOrDefault();
231        if (matchingLocalPlugin != null) {
232          localAndServerPlugins[matchingLocalPlugin] = plugin;
233        }
234      }
235      // refresh the list view with plugins
236      listView.Items.Clear();
237      ignoreItemCheckedEvents = true;
238      foreach (var pair in localAndServerPlugins) {
239        var item = MakeListViewItem(pair.Key);
240        listView.Items.Add(item);
241      }
[3624]242      Util.ResizeColumns(listView.Columns.OfType<ColumnHeader>());
[3612]243      ignoreItemCheckedEvents = false;
244    }
245
[3068]246    private IEnumerable<IPluginDescription> IteratePlugins(IEnumerable<IPluginDescription> plugins) {
[3179]247      HashSet<IPluginDescription> yieldedItems = new HashSet<IPluginDescription>();
[3068]248      foreach (var plugin in plugins) {
249        foreach (var dependency in IteratePlugins(plugin.Dependencies)) {
[3179]250          if (!yieldedItems.Contains(dependency)) {
251            yieldedItems.Add(dependency);
252            yield return dependency;
253          }
[3068]254        }
[3179]255        if (!yieldedItems.Contains(plugin)) {
256          yieldedItems.Add(plugin);
257          yield return plugin;
258        }
[3068]259      }
260    }
261
[4482]262    private static byte[] CreateZipPackage(IPluginDescription plugin) {
[2816]263      using (MemoryStream stream = new MemoryStream()) {
[11650]264        ZipArchive zipFile = new ZipArchive(stream, ZipArchiveMode.Create);
[2816]265        foreach (var file in plugin.Files) {
[11650]266          zipFile.CreateEntry(file.Name);
[2816]267        }
268        stream.Seek(0, SeekOrigin.Begin);
269        return stream.GetBuffer();
270      }
271    }
272
273    private ListViewItem MakeListViewItem(IPluginDescription plugin) {
274      ListViewItem item;
275      if (localAndServerPlugins[plugin] != null) {
[3068]276        item = new ListViewItem(new string[] { plugin.Name, plugin.Version.ToString(),
277          localAndServerPlugins[plugin].Version.ToString(), localAndServerPlugins[plugin].Description });
[3624]278        if (plugin.Version <= localAndServerPlugins[plugin].Version)
279          item.ForeColor = Color.Gray;
[2816]280      } else {
[3068]281        item = new ListViewItem(new string[] { plugin.Name, plugin.Version.ToString(),
282          string.Empty, plugin.Description });
[2802]283      }
284      item.Tag = plugin;
[3608]285      item.ImageIndex = 0;
[2860]286      item.Checked = false;
[2802]287      return item;
288    }
289
[2860]290    private ListViewItem FindItemForPlugin(IPluginDescription dep) {
291      return (from i in listView.Items.Cast<ListViewItem>()
292              where i.Tag == dep
293              select i).Single();
[2802]294    }
295
[3710]296    private DeploymentService.PluginDescription MakePluginDescription(IPluginDescription plugin, Dictionary<IPluginDescription, DeploymentService.PluginDescription> cachedPluginDescriptions) {
297      if (!cachedPluginDescriptions.ContainsKey(plugin)) {
298        var dependencies = (from dep in plugin.Dependencies
299                            select MakePluginDescription(dep, cachedPluginDescriptions))
300                           .ToList();
301        cachedPluginDescriptions.Add(plugin,
302          new DeploymentService.PluginDescription(plugin.Name, plugin.Version, dependencies, plugin.ContactName, plugin.ContactEmail, plugin.LicenseText));
303      }
304      return cachedPluginDescriptions[plugin];
[2816]305    }
[2860]306    #endregion
[2802]307  }
308}
Note: See TracBrowser for help on using the repository browser.