~ubuntu-branches/ubuntu/precise/gnome-do/precise-proposed

« back to all changes in this revision

Viewing changes to Do/src/Do.Core/PluginManager.cs

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2008-09-14 10:09:40 UTC
  • mto: (0.1.8 sid)
  • mto: This revision was merged to the branch mainline in revision 7.
  • Revision ID: james.westby@ubuntu.com-20080914100940-kyghudg7py14bu2z
Tags: upstream-0.6.0.0
ImportĀ upstreamĀ versionĀ 0.6.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* PluginManager.cs
 
2
 *
 
3
 * GNOME Do is the legal property of its developers. Please refer to the
 
4
 * COPYRIGHT file distributed with this
 
5
 * source distribution.
 
6
 *
 
7
 * This program 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
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
 */
 
20
 
 
21
using System;
 
22
using System.IO;
 
23
using System.Collections.Generic;
 
24
 
 
25
using Mono.Addins;
 
26
using Mono.Addins.Gui;
 
27
using Mono.Addins.Setup;
 
28
 
 
29
using Do;
 
30
using Do.Addins;
 
31
using Do.Universe;
 
32
 
 
33
namespace Do.Core {
 
34
 
 
35
    /// <summary>
 
36
    /// PluginManager serves as Do's primary interface to Mono.Addins.
 
37
    /// </summary>
 
38
    public static class PluginManager {
 
39
 
 
40
                public static string AllPluginsRepository {
 
41
                        get {
 
42
                                return "All Available Plugins";
 
43
                        }
 
44
                }
 
45
                
 
46
        private const string DefaultPluginIcon = "folder_tar";
 
47
 
 
48
        private static string[] ExtensionPaths {
 
49
            get {
 
50
                return new string[] {
 
51
                    "/Do/ItemSource",
 
52
                    "/Do/Action",
 
53
                };
 
54
            }
 
55
        }
 
56
        
 
57
        private static Dictionary<string, List<string>> repository_urls;
 
58
        public static IDictionary<string, List<string>> RepositoryUrls {
 
59
            get {
 
60
                if (null == repository_urls) {
 
61
                        repository_urls = new Dictionary<string, List<string>> ();      
 
62
                        
 
63
                        repository_urls ["Official Plugins"] = new List<string> ();
 
64
                        repository_urls ["Official Plugins"].Add 
 
65
                                ("http://do.davebsd.com/repo/" + Version +"/official");
 
66
                                        
 
67
                        repository_urls ["Community Plugins"] = new List<string> ();
 
68
                        repository_urls ["Community Plugins"].Add
 
69
                                ("http://do.davebsd.com/repo/" + Version +"/community");
 
70
                        
 
71
                        repository_urls ["Local Plugins"] = new List<string> ();
 
72
                        foreach (string repo in Paths.SystemPlugins) {
 
73
                                if (Directory.Exists (repo)) {
 
74
                                                        repository_urls ["Local Plugins"].Add ("file://" + repo);
 
75
                                                }
 
76
                                        }
 
77
                }
 
78
                
 
79
                return repository_urls;;
 
80
            }
 
81
        }
 
82
 
 
83
                private static string Version {
 
84
                        get {
 
85
                                System.Reflection.AssemblyName name;
 
86
                                
 
87
                                name = typeof (PluginManager).Assembly.GetName ();
 
88
                                return String.Format ("{0}.{1}.{2}",
 
89
                                        name.Version.Major, name.Version.Minor, name.Version.Build);
 
90
                        }
 
91
                }
 
92
 
 
93
        /// <summary>
 
94
        /// Performs plugin system initialization. Should be called before this
 
95
        /// class or any Mono.Addins class is used.
 
96
        /// </summary>
 
97
        internal static void Initialize ()
 
98
        {
 
99
            // Initialize Mono.Addins.
 
100
            AddinManager.Initialize (Paths.UserPlugins);
 
101
            AddinManager.AddExtensionNodeHandler ("/Do/ItemSource", OnIObjectChange);
 
102
            AddinManager.AddExtensionNodeHandler ("/Do/Action",  OnIObjectChange);
 
103
 
 
104
            // Register repositories.
 
105
            SetupService setup = new SetupService (AddinManager.Registry);
 
106
                        foreach (List<string> urls in RepositoryUrls.Values) {
 
107
                                foreach (string url in urls) {
 
108
                                        if (!setup.Repositories.ContainsRepository (url)) {
 
109
                                                setup.Repositories.RegisterRepository (null, url, false);
 
110
                                        }
 
111
                                }
 
112
                        }
 
113
            InstallLocalPlugins (setup);
 
114
        }
 
115
        
 
116
        public static bool AddinIsFromRepository (Addin a, string name)
 
117
                {
 
118
                        List<string> urls;
 
119
                        if (name == AllPluginsRepository) return true;
 
120
                        RepositoryUrls.TryGetValue (name, out urls);
 
121
                        foreach (string url in urls) {
 
122
                                if (a.Description.Url.StartsWith (url))
 
123
                                        return true;
 
124
                        }
 
125
                        return false;
 
126
                }
 
127
                
 
128
                public static bool AddinIsFromRepository (AddinRepositoryEntry e,
 
129
                                                                                                  string name)
 
130
                {
 
131
                        List<string> urls;
 
132
                        if (name == AllPluginsRepository) return true;
 
133
                        RepositoryUrls.TryGetValue (name, out urls);
 
134
                        foreach (string url in urls) {
 
135
                                if (e.RepositoryUrl.StartsWith (url))
 
136
                                        return true;
 
137
                        }
 
138
                        return false;
 
139
                }
 
140
 
 
141
        /// <summary>
 
142
        /// Given an addin ID, returns an icon that may represent that addin.
 
143
        /// </summary>
 
144
        /// <param name="id">
 
145
        /// A <see cref="System.String"/> containing an addin ID.
 
146
        /// </param>
 
147
        /// <returns>
 
148
        /// A <see cref="System.String"/> containing an icon name. Can be loaded
 
149
        /// via IconProvider.
 
150
        /// </returns>
 
151
        public static string IconForAddin (string id)
 
152
        {
 
153
            // First look for an icon among ItemSources:
 
154
            foreach (IItemSource obj in ObjectsForAddin<IItemSource> (id)) {
 
155
                                try {
 
156
                                        if (null != obj.Icon)
 
157
                                                return obj.Icon;
 
158
                                } catch { }
 
159
            }
 
160
            // If no icon found among ItemSources, look for an icon among
 
161
            // Actions:         
 
162
            foreach (IAction obj in ObjectsForAddin<IAction> (id)) {
 
163
                                try {
 
164
                                        if (null != obj.Icon)
 
165
                                                return obj.Icon;
 
166
                                } catch { }
 
167
            }
 
168
            return DefaultPluginIcon;
 
169
        }
 
170
 
 
171
        /// <summary>
 
172
        /// Finds all plugged-in item sources.
 
173
        /// </summary>
 
174
        /// <returns>
 
175
        /// A <see cref="ICollection`1"/> of DoItemSource instances loaded from
 
176
        /// plugins.
 
177
        /// </returns>
 
178
        internal static ICollection<DoItemSource> GetItemSources () {
 
179
            List<DoItemSource> sources;
 
180
 
 
181
            sources = new List<DoItemSource> ();
 
182
            foreach (IItemSource source in
 
183
                AddinManager.GetExtensionObjects ("/Do/ItemSource")) {
 
184
                sources.Add (new DoItemSource (source));
 
185
            }
 
186
            return sources;
 
187
        }
 
188
 
 
189
        /// <summary>
 
190
        /// Finds all plugged-in actions.
 
191
        /// </summary>
 
192
        /// <returns>
 
193
        /// A <see cref="ICollection`1"/> of DoAction instances loaded from
 
194
        /// plugins.
 
195
        /// </returns>
 
196
        internal static ICollection<DoAction> GetActions () {
 
197
            List<DoAction> actions;
 
198
 
 
199
            actions = new List<DoAction> ();
 
200
            foreach (IAction action in
 
201
                AddinManager.GetExtensionObjects ("/Do/Action")) {
 
202
                actions.Add (new DoAction (action));
 
203
            }
 
204
            return actions;
 
205
        }
 
206
 
 
207
        /// <summary>
 
208
        /// Install all available plugin updates, either
 
209
        /// graphically or non-graphically.
 
210
        /// </summary>
 
211
        /// <param name="graphical">
 
212
        /// A <see cref="System.Boolean"/> to determine whether installer should
 
213
        /// be graphical (true iff graphical installer should be used).
 
214
        /// </param>
 
215
        /// <returns>
 
216
        /// A <see cref="System.Boolean"/> indicating whether any updates were
 
217
        /// performed.
 
218
        /// </returns>
 
219
        internal static bool InstallAvailableUpdates (bool graphical)
 
220
        {
 
221
            SetupService setup;
 
222
            List<string> updates;
 
223
            IAddinInstaller installer;
 
224
 
 
225
            updates = new List<string> ();
 
226
            setup = new SetupService (AddinManager.Registry);
 
227
            installer = graphical ? new DoAddinInstaller () as IAddinInstaller
 
228
                : new ConsoleAddinInstaller () as IAddinInstaller ;
 
229
                        
 
230
            setup.Repositories.UpdateAllRepositories (
 
231
                new ConsoleProgressStatus (true));
 
232
            foreach (AddinRepositoryEntry rep in
 
233
                setup.Repositories.GetAvailableAddins ()) {
 
234
                Addin installed;
 
235
 
 
236
                installed = AddinManager.Registry.GetAddin (Addin.GetIdName (
 
237
                    rep.Addin.Id));
 
238
                if (null == installed) continue;
 
239
                if (Addin.CompareVersions (installed.Version, rep.Addin.Version) > 0) {
 
240
                    updates.Add (rep.Addin.Id);
 
241
                }
 
242
            }
 
243
            if (updates.Count > 0) {
 
244
                installer.InstallAddins (
 
245
                    AddinManager.Registry, string.Empty, updates.ToArray ());
 
246
            }
 
247
            return updates.Count > 0;
 
248
        }
 
249
        
 
250
        /// <summary>
 
251
        /// Checks if there are any updates available for download/installatition
 
252
        /// </summary>
 
253
        /// <returns>
 
254
        /// A <see cref="System.Boolean"/> representing whether or not there
 
255
        /// are any updates available for install
 
256
        /// </returns>
 
257
        public static bool UpdatesAvailable ()
 
258
        {
 
259
                SetupService setup;
 
260
            setup = new SetupService (AddinManager.Registry);
 
261
                setup.Repositories.UpdateAllRepositories (
 
262
                        new ConsoleProgressStatus (true));
 
263
            foreach (AddinRepositoryEntry rep in
 
264
                setup.Repositories.GetAvailableAddins ()) {
 
265
                Addin installed;
 
266
 
 
267
                installed = AddinManager.Registry.GetAddin (Addin.GetIdName (
 
268
                    rep.Addin.Id));
 
269
                if (null == installed) continue;
 
270
                if (Addin.CompareVersions (installed.Version, rep.Addin.Version) > 0) {
 
271
                    return true;
 
272
                }
 
273
            }
 
274
            return false;
 
275
        }
 
276
 
 
277
        /// <summary>
 
278
        /// Installs plugins that are located in the <see
 
279
        /// cref="Paths.UserPlugins"/> directory.  This will build addins
 
280
        /// (mpack files) and install them.
 
281
        /// </summary>
 
282
        /// <param name="setup">
 
283
        /// A <see cref="SetupService"/>
 
284
        /// </param>
 
285
        internal static void InstallLocalPlugins (SetupService setup)
 
286
        {
 
287
            // Create mpack (addin packages) out of dlls.
 
288
            foreach (string file in 
 
289
                Directory.GetFiles (Paths.UserPlugins, "*.dll")) {
 
290
                string path;
 
291
 
 
292
                path = Path.Combine (Paths.UserPlugins, file);
 
293
                setup.BuildPackage (new ConsoleProgressStatus (false),
 
294
                    Paths.UserPlugins, new string [] { path });
 
295
            }
 
296
                        
 
297
                        //Delete dlls.  If we do it earlier why might delete dll's brought in as
 
298
                        //dependancies.  Doing it now has the same effect without breakage.
 
299
                        foreach (string file in 
 
300
                Directory.GetFiles (Paths.UserPlugins, "*.dll")) {
 
301
                string path;
 
302
 
 
303
                path = Path.Combine (Paths.UserPlugins, file);
 
304
                File.Delete (path);
 
305
            }
 
306
            // Install each mpack file, deleting each file when finished
 
307
            // installing it.
 
308
            foreach (string file in 
 
309
                    Directory.GetFiles (Paths.UserPlugins, "*.mpack")) {
 
310
                string path;
 
311
 
 
312
                path = Path.Combine (Paths.UserPlugins, file);
 
313
                setup.Install (new ConsoleProgressStatus (false),
 
314
                    new string [] { path });
 
315
                File.Delete (path);
 
316
            }
 
317
        }
 
318
 
 
319
        internal static void OnIObjectChange (object s,
 
320
                                              ExtensionNodeEventArgs args)
 
321
        {
 
322
            TypeExtensionNode node;
 
323
 
 
324
            node = args.ExtensionNode as TypeExtensionNode;
 
325
            if (args.Change.Equals (ExtensionChange.Add)) {
 
326
                try {
 
327
                                        // plugin is to be used only for inspection here.
 
328
                                        IObject plugin = node.GetInstance () as IObject;
 
329
                                        // Wrap in a DoObject for safety.
 
330
                    IObject o = new DoObject (plugin);
 
331
                                        if (plugin is Pluggable)
 
332
                                                (plugin as Pluggable).NotifyLoad ();                                    
 
333
                    Log.Info ("Loaded \"{0}\".", o.Name);
 
334
                } catch (Exception e) {
 
335
                    Log.Error ("Encountered error loading \"{0}\": {0}",
 
336
                        e.Message);
 
337
                                        Log.Debug (e.StackTrace);
 
338
                }
 
339
            } else {
 
340
                try {
 
341
                                        IObject plugin = node.GetInstance() as IObject;
 
342
                    IObject o = new DoObject (plugin);
 
343
                                        if (plugin is Pluggable)
 
344
                                                (plugin as Pluggable).NotifyUnload ();
 
345
                    Log.Info ("Unloaded \"{0}\".", o.Name);
 
346
                } catch (Exception e) {
 
347
                    Log.Error ("Encountered error unloading plugin: {0}",
 
348
                        e.Message);
 
349
                                        Log.Debug (e.StackTrace);
 
350
                }
 
351
            }   
 
352
        }
 
353
 
 
354
                /// <summary>
 
355
                /// Get all objects conforming to type T provided by a given addin.
 
356
                /// </summary>
 
357
                /// <param name="id">
 
358
                /// A <see cref="System.String"/> containing an addin id.
 
359
                /// </param>
 
360
                /// <returns>
 
361
                /// A <see cref="ICollection`1"/> of instances of type T.
 
362
                /// </returns>
 
363
        private static ICollection<T> ObjectsForAddin<T> (string id)
 
364
        {
 
365
            List<T> obs;
 
366
 
 
367
            obs = new List<T> ();
 
368
            foreach (string path in ExtensionPaths) {
 
369
                foreach (TypeExtensionNode n in
 
370
                    AddinManager.GetExtensionNodes (path)) {
 
371
                    object instance;
 
372
                    bool addinMatch, typeMatch;
 
373
 
 
374
                    try {
 
375
                        instance = n.GetInstance ();
 
376
                    } catch {
 
377
                        continue;
 
378
                    }
 
379
                    addinMatch =
 
380
                        Addin.GetIdName (id) == Addin.GetIdName (n.Addin.Id);
 
381
                    typeMatch =
 
382
                        typeof (T).IsAssignableFrom (instance.GetType ());
 
383
                    if (addinMatch && typeMatch) {
 
384
                        obs.Add ((T) instance);
 
385
                    }
 
386
                }
 
387
            }
 
388
            return obs;
 
389
        }
 
390
 
 
391
                /// <summary>
 
392
                /// Get all IConfigurable instances loaded from plugins.
 
393
                /// </summary>
 
394
                /// <param name="id">
 
395
                /// A <see cref="System.String"/> containing an addin id.
 
396
                /// </param>
 
397
                /// <returns>
 
398
                /// A <see cref="ICollection`1"/> of <see cref="IConfigurable"/>
 
399
                /// provided by the addin for that id.
 
400
                /// </returns>
 
401
        internal static ICollection<IConfigurable> ConfigurablesForAddin (string id)
 
402
        {
 
403
            List<IConfigurable> cons;
 
404
 
 
405
            cons = new List<IConfigurable> ();  
 
406
            foreach (IConfigurable con in ObjectsForAddin<IConfigurable> (id))
 
407
                cons.Add (new DoObject (con));
 
408
            return cons;
 
409
        }
 
410
    }
 
411
}
 
 
b'\\ No newline at end of file'