Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 3539 was 3509, checked in by gkronber, 15 years ago

Reintegrated plugin administration controls. #989

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