Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.PluginInfrastructure/Advanced/PluginEditor.cs @ 3600

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

Implemented reviewer comments in plugin infrastructure. #989 (Implement review comments in plugin infrastructure)

File size: 12.6 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 PluginEditor : UserControl {
37    private Dictionary<IPluginDescription, IPluginDescription> localAndServerPlugins;
38    private BackgroundWorker pluginUploadWorker;
39    private BackgroundWorker updateServerPluginsWorker;
40
41    private PluginManager pluginManager;
42    public PluginManager PluginManager {
43      get { return pluginManager; }
44      set {
45        // if (value == null) throw new ArgumentNullException();
46        pluginManager = value;
47      }
48    }
49
50    public PluginEditor() {
51      InitializeComponent();
52      // Caption = "Upload Plugins";
53
54      localAndServerPlugins = new Dictionary<IPluginDescription, IPluginDescription>();
55
56      #region initialize backgroundworkers
57      pluginUploadWorker = new BackgroundWorker();
58      pluginUploadWorker.DoWork += new DoWorkEventHandler(pluginUploadWorker_DoWork);
59      pluginUploadWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(pluginUploadWorker_RunWorkerCompleted);
60
61      updateServerPluginsWorker = new BackgroundWorker();
62      updateServerPluginsWorker.DoWork += new DoWorkEventHandler(updateServerPluginsWorker_DoWork);
63      updateServerPluginsWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(updateServerPluginsWorker_RunWorkerCompleted);
64      #endregion
65    }
66
67    #region refresh plugins from server backgroundworker
68    void updateServerPluginsWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
69      if (e.Error != null) {
70        MessageBox.Show("There was an error while connecting to the server." + Environment.NewLine +
71                   "Please check your connection settings and user credentials.");
72        UpdateControlsDisconnectedState();
73      } else {
74        // refresh local plugins
75        localAndServerPlugins.Clear();
76        foreach (var plugin in pluginManager.Plugins) {
77          localAndServerPlugins.Add(plugin, null);
78        }
79        // refresh server plugins (find matching local plugins)
80        var plugins = (IPluginDescription[])e.Result;
81        foreach (var plugin in plugins) {
82          var matchingLocalPlugin = (from localPlugin in localAndServerPlugins.Keys
83                                     where localPlugin.Name == plugin.Name
84                                     where localPlugin.Version == localPlugin.Version
85                                     select localPlugin).SingleOrDefault();
86          if (matchingLocalPlugin != null) {
87            localAndServerPlugins[matchingLocalPlugin] = plugin;
88          }
89        }
90        // refresh the list view with plugins
91        listView.Items.Clear();
92        listView.CheckBoxes = false;
93        //suppressCheckedEvents = true;
94        foreach (var pair in localAndServerPlugins) {
95          var item = MakeListViewItem(pair.Key);
96          listView.Items.Add(item);
97        }
98        foreach (ColumnHeader column in listView.Columns)
99          if (listView.Items.Count > 0)
100            column.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
101          else column.AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize);
102        //listView.suppressCheckedEvents = false;
103        listView.CheckBoxes = true;
104        UpdateControlsConnectedState();
105      }
106      // make sure cursor is set correctly
107      Cursor = Cursors.Default;
108    }
109
110    void updateServerPluginsWorker_DoWork(object sender, DoWorkEventArgs e) {
111      var client = DeploymentService.UpdateClientFactory.CreateClient();
112      e.Result = client.GetPlugins();
113    }
114    #endregion
115
116    #region upload plugins to server backgroundworker
117    void pluginUploadWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
118      Cursor = Cursors.Default;
119      if (e.Error != null) {
120        MessageBox.Show("There was an error while connecting to the server." + Environment.NewLine +
121                   "Please check your connection settings and user credentials.");
122        UpdateControlsDisconnectedState();
123      } else {
124        UpdateControlsConnectedState();
125        // start another async call to refresh plugin information from server
126        RefreshPluginsAsync();
127      }
128    }
129
130    void pluginUploadWorker_DoWork(object sender, DoWorkEventArgs e) {
131      var selectedPlugins = (IEnumerable<IPluginDescription>)e.Argument;
132      DeploymentService.AdminClient adminClient = DeploymentService.AdminClientFactory.CreateClient();
133
134      foreach (var plugin in IteratePlugins(selectedPlugins)) {
135        SetMainFormStatusBar("Uploading", plugin);
136        adminClient.DeployPlugin(MakePluginDescription(plugin), CreateZipPackage(plugin));
137      }
138    }
139
140    #endregion
141
142
143    #region button events
144    private void uploadButton_Click(object sender, EventArgs e) {
145      var selectedPlugins = from item in listView.Items.Cast<ListViewItem>()
146                            where item.Checked
147                            where item.Tag is IPluginDescription
148                            select item.Tag as IPluginDescription;
149      if (selectedPlugins.Count() > 0) {
150        Cursor = Cursors.AppStarting;
151        DisableControl();
152        pluginUploadWorker.RunWorkerAsync(selectedPlugins.ToList());
153      }
154    }
155
156    private void refreshButton_Click(object sender, EventArgs e) {
157      DisableControl();
158      RefreshPluginsAsync();
159    }
160
161    #endregion
162
163    #region item list events
164    private void listView_ItemActivate(object sender, EventArgs e) {
165      foreach (var item in listView.SelectedItems) {
166        var plugin = (PluginDescription)((ListViewItem)item).Tag;
167        var compView = new PluginComparisonView(plugin, localAndServerPlugins[plugin]);
168        compView.Show();
169      }
170    }
171
172    private void listView_ItemChecked(object sender, ItemCheckedEventArgs e) {
173      List<IPluginDescription> modifiedPlugins = new List<IPluginDescription>();
174      if (e.Item.Checked) {
175        foreach (ListViewItem item in listView.SelectedItems) {
176          var plugin = (IPluginDescription)item.Tag;
177          // also check all dependencies
178          if (!modifiedPlugins.Contains(plugin))
179            modifiedPlugins.Add(plugin);
180          foreach (var dep in GetAllDependencies(plugin)) {
181            if (!modifiedPlugins.Contains(dep))
182              modifiedPlugins.Add(dep);
183          }
184        }
185        listView.CheckItems(modifiedPlugins.Select(x => FindItemForPlugin(x)));
186      } else {
187        foreach (ListViewItem item in listView.SelectedItems) {
188          var plugin = (IPluginDescription)item.Tag;
189          // also uncheck all dependent plugins
190          if (!modifiedPlugins.Contains(plugin))
191            modifiedPlugins.Add(plugin);
192          foreach (var dep in GetAllDependents(plugin)) {
193            if (!modifiedPlugins.Contains(dep))
194              modifiedPlugins.Add(dep);
195          }
196        }
197        listView.UncheckItems(modifiedPlugins.Select(x => FindItemForPlugin(x)));
198      }
199      uploadButton.Enabled = (from i in listView.Items.OfType<ListViewItem>()
200                              where i.Checked
201                              select i).Any();
202    }
203    #endregion
204
205    #region helper methods
206    private IEnumerable<IPluginDescription> GetAllDependents(IPluginDescription plugin) {
207      return from p in localAndServerPlugins.Keys
208             let matchingEntries = from dep in GetAllDependencies(p)
209                                   where dep.Name == plugin.Name
210                                   where dep.Version == plugin.Version
211                                   select dep
212             where matchingEntries.Any()
213             select p;
214    }
215
216    private IEnumerable<IPluginDescription> GetAllDependencies(IPluginDescription plugin) {
217      foreach (var dep in plugin.Dependencies) {
218        foreach (var recDep in GetAllDependencies(dep)) {
219          yield return recDep;
220        }
221        yield return dep;
222      }
223    }
224
225    private IEnumerable<IPluginDescription> IteratePlugins(IEnumerable<IPluginDescription> plugins) {
226      HashSet<IPluginDescription> yieldedItems = new HashSet<IPluginDescription>();
227      foreach (var plugin in plugins) {
228        foreach (var dependency in IteratePlugins(plugin.Dependencies)) {
229          if (!yieldedItems.Contains(dependency)) {
230            yieldedItems.Add(dependency);
231            yield return dependency;
232          }
233        }
234        if (!yieldedItems.Contains(plugin)) {
235          yieldedItems.Add(plugin);
236          yield return plugin;
237        }
238      }
239    }
240
241    private byte[] CreateZipPackage(IPluginDescription plugin) {
242      using (MemoryStream stream = new MemoryStream()) {
243        ZipFile zipFile = new ZipFile(stream);
244        zipFile.BeginUpdate();
245        foreach (var file in plugin.Files) {
246          zipFile.Add(file.Name);
247        }
248        zipFile.CommitUpdate();
249        stream.Seek(0, SeekOrigin.Begin);
250        return stream.GetBuffer();
251      }
252    }
253
254    private ListViewItem MakeListViewItem(IPluginDescription plugin) {
255      ListViewItem item;
256      if (localAndServerPlugins[plugin] != null) {
257        item = new ListViewItem(new string[] { plugin.Name, plugin.Version.ToString(),
258          localAndServerPlugins[plugin].Version.ToString(), localAndServerPlugins[plugin].Description });
259      } else {
260        item = new ListViewItem(new string[] { plugin.Name, plugin.Version.ToString(),
261          string.Empty, plugin.Description });
262      }
263      item.Tag = plugin;
264      item.Checked = false;
265      return item;
266    }
267
268    private ListViewItem FindItemForPlugin(IPluginDescription dep) {
269      return (from i in listView.Items.Cast<ListViewItem>()
270              where i.Tag == dep
271              select i).Single();
272    }
273
274    private DeploymentService.PluginDescription MakePluginDescription(IPluginDescription plugin) {
275      var dependencies = from dep in plugin.Dependencies
276                         select MakePluginDescription(dep);
277      return new DeploymentService.PluginDescription(plugin.Name, plugin.Version, dependencies, plugin.ContactName, plugin.ContactEmail, plugin.LicenseText);
278    }
279
280    // start background process to refresh the plugin list (local and server)
281    private void RefreshPluginsAsync() {
282      Cursor = Cursors.AppStarting;
283      DisableControl();
284      updateServerPluginsWorker.RunWorkerAsync();
285    }
286
287    // is called by all methods that start a background process
288    // controls must be enabled manuall again when the backgroundworker finishes
289    private void DisableControl() {
290      //MainFormManager.GetMainForm<MainForm>().ShowProgressBar();
291      foreach (Control ctrl in Controls)
292        ctrl.Enabled = false;
293    }
294
295    private void UpdateControlsDisconnectedState() {
296      refreshButton.Enabled = false;
297
298      localAndServerPlugins.Clear();
299      listView.Items.Clear();
300      listView.Enabled = false;
301      uploadButton.Enabled = false;
302      //MainFormManager.GetMainForm<MainForm>().HideProgressBar();
303    }
304
305    private void UpdateControlsConnectedState() {
306      refreshButton.Enabled = true;
307      listView.Enabled = true;
308      uploadButton.Enabled = false;
309      //MainFormManager.GetMainForm<MainForm>().HideProgressBar();
310    }
311    private void SetMainFormStatusBar(string p, IPluginDescription plugin) {
312      if (InvokeRequired) Invoke((Action<string, IPluginDescription>)SetMainFormStatusBar, p, plugin);
313      else {
314        //MainFormManager.GetMainForm<MainForm>().SetStatusBarText(p + " " + plugin.ToString());
315      }
316    }
317
318    #endregion
319  }
320}
Note: See TracBrowser for help on using the repository browser.