Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2521_ProblemRefactoring/HeuristicLab.PluginInfrastructure/3.3/Advanced/UploadPluginsView.cs @ 15697

Last change on this file since 15697 was 12012, checked in by ascheibe, 10 years ago

#2212 merged r12008, r12009, r12010 back into trunk

File size: 12.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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
21
22using System;
23using System.Collections.Generic;
24using System.ComponentModel;
25using System.Drawing;
26using System.IO;
27using System.IO.Compression;
28using System.Linq;
29using System.ServiceModel;
30using System.Windows.Forms;
31using HeuristicLab.PluginInfrastructure.Manager;
32
33namespace HeuristicLab.PluginInfrastructure.Advanced {
34  internal partial class UploadPluginsView : InstallationManagerControl {
35    private const string UploadMessage = "Uploading plugins...";
36    private const string RefreshMessage = "Downloading plugin information from deployment service...";
37
38    private Dictionary<IPluginDescription, IPluginDescription> localAndServerPlugins;
39    private BackgroundWorker pluginUploadWorker;
40    private BackgroundWorker refreshPluginsWorker;
41
42    private PluginManager pluginManager;
43    public PluginManager PluginManager {
44      get { return pluginManager; }
45      set { pluginManager = value; }
46    }
47
48    public UploadPluginsView() {
49      InitializeComponent();
50      pluginImageList.Images.Add(HeuristicLab.PluginInfrastructure.Resources.Plugin);
51      localAndServerPlugins = new Dictionary<IPluginDescription, IPluginDescription>();
52
53      #region initialize backgroundworkers
54      pluginUploadWorker = new BackgroundWorker();
55      pluginUploadWorker.DoWork += new DoWorkEventHandler(pluginUploadWorker_DoWork);
56      pluginUploadWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(pluginUploadWorker_RunWorkerCompleted);
57
58      refreshPluginsWorker = new BackgroundWorker();
59      refreshPluginsWorker.DoWork += new DoWorkEventHandler(refreshPluginsWorker_DoWork);
60      refreshPluginsWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(refreshPluginsWorker_RunWorkerCompleted);
61      #endregion
62    }
63
64    #region refresh plugins from server backgroundworker
65    void refreshPluginsWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
66      if (e.Error != null) {
67        StatusView.ShowError("Connection Error",
68          "There was an error while connecting to the server." + Environment.NewLine +
69                   "Please check your connection settings and user credentials.");
70      } else {
71        UpdatePluginListView((IEnumerable<IPluginDescription>)e.Result);
72      }
73      StatusView.HideProgressIndicator();
74      StatusView.RemoveMessage(RefreshMessage);
75      StatusView.UnlockUI();
76    }
77
78    void refreshPluginsWorker_DoWork(object sender, DoWorkEventArgs e) {
79      // refresh available plugins
80      var client = DeploymentService.UpdateServiceClientFactory.CreateClient();
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      }
97    }
98    #endregion
99
100    #region upload plugins to server backgroundworker
101    void pluginUploadWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
102      if (e.Error != null) {
103        StatusView.ShowError("Connection Error",
104          "There was an error while connecting to the server." + Environment.NewLine +
105                   "Please check your connection settings and user credentials.");
106      } else {
107        UpdatePluginListView((IEnumerable<IPluginDescription>)e.Result);
108      }
109      StatusView.RemoveMessage(UploadMessage);
110      StatusView.HideProgressIndicator();
111      StatusView.UnlockUI();
112    }
113
114    void pluginUploadWorker_DoWork(object sender, DoWorkEventArgs e) {
115      // upload plugins
116      var selectedPlugins = (IEnumerable<IPluginDescription>)e.Argument;
117      DeploymentService.AdminServiceClient adminClient = DeploymentService.AdminServiceClientFactory.CreateClient();
118      Dictionary<IPluginDescription, DeploymentService.PluginDescription> cachedPluginDescriptions =
119        new Dictionary<IPluginDescription, DeploymentService.PluginDescription>();
120      try {
121        foreach (var plugin in IteratePlugins(selectedPlugins)) {
122          adminClient.DeployPlugin(MakePluginDescription(plugin, cachedPluginDescriptions), CreateZipPackage(plugin));
123        }
124        adminClient.Close();
125      }
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
139      var client = DeploymentService.UpdateServiceClientFactory.CreateClient();
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      }
156    }
157    #endregion
158
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) {
167        StatusView.LockUI();
168        StatusView.ShowProgressIndicator();
169        StatusView.ShowMessage(UploadMessage);
170        pluginUploadWorker.RunWorkerAsync(selectedPlugins.ToList());
171      }
172    }
173
174    private void refreshButton_Click(object sender, EventArgs e) {
175      StatusView.LockUI();
176      StatusView.ShowProgressIndicator();
177      StatusView.ShowMessage(RefreshMessage);
178      refreshPluginsWorker.RunWorkerAsync();
179    }
180
181    #endregion
182
183    #region item list events
184    private bool ignoreItemCheckedEvents = false;
185    private void listView_ItemChecked(object sender, ItemCheckedEventArgs e) {
186      if (ignoreItemCheckedEvents) return;
187      List<IPluginDescription> modifiedPlugins = new List<IPluginDescription>();
188      if (e.Item.Checked) {
189        foreach (ListViewItem item in listView.SelectedItems) {
190          var plugin = (IPluginDescription)item.Tag;
191          // also check all dependencies
192          if (!modifiedPlugins.Contains(plugin))
193            modifiedPlugins.Add(plugin);
194          foreach (var dep in Util.GetAllDependencies(plugin)) {
195            if (!modifiedPlugins.Contains(dep))
196              modifiedPlugins.Add(dep);
197          }
198        }
199        listView.CheckItems(modifiedPlugins.Select(x => FindItemForPlugin(x)));
200      } else {
201        foreach (ListViewItem item in listView.SelectedItems) {
202          var plugin = (IPluginDescription)item.Tag;
203          // also uncheck all dependent plugins
204          if (!modifiedPlugins.Contains(plugin))
205            modifiedPlugins.Add(plugin);
206          foreach (var dep in Util.GetAllDependents(plugin, localAndServerPlugins.Keys)) {
207            if (!modifiedPlugins.Contains(dep))
208              modifiedPlugins.Add(dep);
209          }
210        }
211        listView.UncheckItems(modifiedPlugins.Select(x => FindItemForPlugin(x)));
212      }
213      uploadButton.Enabled = (from i in listView.Items.OfType<ListViewItem>()
214                              where i.Checked
215                              select i).Any();
216    }
217    #endregion
218
219    #region helper methods
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
229                                   where localPlugin.Version == plugin.Version
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      }
242      Util.ResizeColumns(listView.Columns.OfType<ColumnHeader>());
243      ignoreItemCheckedEvents = false;
244    }
245
246    private IEnumerable<IPluginDescription> IteratePlugins(IEnumerable<IPluginDescription> plugins) {
247      HashSet<IPluginDescription> yieldedItems = new HashSet<IPluginDescription>();
248      foreach (var plugin in plugins) {
249        foreach (var dependency in IteratePlugins(plugin.Dependencies)) {
250          if (!yieldedItems.Contains(dependency)) {
251            yieldedItems.Add(dependency);
252            yield return dependency;
253          }
254        }
255        if (!yieldedItems.Contains(plugin)) {
256          yieldedItems.Add(plugin);
257          yield return plugin;
258        }
259      }
260    }
261
262    private static byte[] CreateZipPackage(IPluginDescription plugin) {
263      using (MemoryStream stream = new MemoryStream()) {
264        ZipArchive zipFile = new ZipArchive(stream, ZipArchiveMode.Create);
265        foreach (var file in plugin.Files) {
266          zipFile.CreateEntry(file.Name);
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) {
276        item = new ListViewItem(new string[] { plugin.Name, plugin.Version.ToString(),
277          localAndServerPlugins[plugin].Version.ToString(), localAndServerPlugins[plugin].Description });
278        if (plugin.Version <= localAndServerPlugins[plugin].Version)
279          item.ForeColor = Color.Gray;
280      } else {
281        item = new ListViewItem(new string[] { plugin.Name, plugin.Version.ToString(),
282          string.Empty, plugin.Description });
283      }
284      item.Tag = plugin;
285      item.ImageIndex = 0;
286      item.Checked = false;
287      return item;
288    }
289
290    private ListViewItem FindItemForPlugin(IPluginDescription dep) {
291      return (from i in listView.Items.Cast<ListViewItem>()
292              where i.Tag == dep
293              select i).Single();
294    }
295
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];
305    }
306    #endregion
307  }
308}
Note: See TracBrowser for help on using the repository browser.