Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3.2/sources/HeuristicLab.PluginInfrastructure/Advanced/PluginEditor.cs @ 10159

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

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

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