Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.PluginInfrastructure/Advanced/UploadPluginsView.cs @ 3710

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

Implemented reviewer comments. #893 (HeuristicLab 3.3.0 application review)

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