~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/mono-addins/Mono.Addins.Setup/Mono.Addins.Setup/RepositoryRegistry.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// RepositoryRegistry.cs
 
3
//
 
4
// Author:
 
5
//   Lluis Sanchez Gual
 
6
//
 
7
// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
 
8
//
 
9
// Permission is hereby granted, free of charge, to any person obtaining
 
10
// a copy of this software and associated documentation files (the
 
11
// "Software"), to deal in the Software without restriction, including
 
12
// without limitation the rights to use, copy, modify, merge, publish,
 
13
// distribute, sublicense, and/or sell copies of the Software, and to
 
14
// permit persons to whom the Software is furnished to do so, subject to
 
15
// the following conditions:
 
16
// 
 
17
// The above copyright notice and this permission notice shall be
 
18
// included in all copies or substantial portions of the Software.
 
19
// 
 
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
27
//
 
28
 
 
29
 
 
30
using System;
 
31
using System.Linq;
 
32
using System.IO;
 
33
using System.Collections;
 
34
using Mono.Addins.Setup.ProgressMonitoring;
 
35
using System.Collections.Generic;
 
36
 
 
37
namespace Mono.Addins.Setup
 
38
{
 
39
        /// <summary>
 
40
        /// A registry of on-line repositories
 
41
        /// </summary>
 
42
        /// <remarks>
 
43
        /// This class can be used to manage on-line repository subscriptions.
 
44
        /// </remarks>
 
45
        public class RepositoryRegistry
 
46
        {
 
47
                ArrayList repoList;
 
48
                SetupService service;
 
49
                
 
50
                internal RepositoryRegistry (SetupService service)
 
51
                {
 
52
                        this.service = service;
 
53
                }
 
54
                
 
55
                /// <summary>
 
56
                /// Subscribes to an on-line repository
 
57
                /// </summary>
 
58
                /// <param name="monitor">
 
59
                /// Progress monitor where to show progress status and log
 
60
                /// </param>
 
61
                /// <param name="url">
 
62
                /// URL of the repository
 
63
                /// </param>
 
64
                /// <returns>
 
65
                /// A repository reference
 
66
                /// </returns>
 
67
                /// <remarks>
 
68
                /// The repository index is not downloaded by default. It can be downloaded
 
69
                /// by calling UpdateRepository.
 
70
                /// </remarks>
 
71
                public AddinRepository RegisterRepository (IProgressStatus monitor, string url)
 
72
                {
 
73
                        return RegisterRepository (monitor, url, false);
 
74
                }
 
75
                
 
76
                /// <summary>
 
77
                /// Subscribes to an on-line repository
 
78
                /// </summary>
 
79
                /// <param name="monitor">
 
80
                /// Progress monitor where to show progress status and log
 
81
                /// </param>
 
82
                /// <param name="url">
 
83
                /// URL of the repository
 
84
                /// </param>
 
85
                /// <param name="updateNow">
 
86
                /// When set to True, the repository index will be downloaded.
 
87
                /// </param>
 
88
                /// <returns>
 
89
                /// A repository reference
 
90
                /// </returns>
 
91
                public AddinRepository RegisterRepository (IProgressStatus monitor, string url, bool updateNow)
 
92
                {
 
93
                        if (string.IsNullOrEmpty (url))
 
94
                                throw new ArgumentException ("Emtpy url");
 
95
                        
 
96
                        if (!url.EndsWith (".mrep")) {
 
97
                                if (url [url.Length - 1] != '/')
 
98
                                        url += "/";
 
99
                                url = url + "main.mrep";
 
100
                        }
 
101
                        
 
102
                        RepositoryRecord rr = FindRepositoryRecord (url);
 
103
                        if (rr != null)
 
104
                                return rr;
 
105
 
 
106
                        rr = RegisterRepository (url, false);
 
107
                        
 
108
                        try {
 
109
                                if (updateNow) {
 
110
                                        UpdateRepository (monitor, url);
 
111
                                        rr = FindRepositoryRecord (url);
 
112
                                        Repository rep = rr.GetCachedRepository ();
 
113
                                        if (rep != null)
 
114
                                                rr.Name = rep.Name;
 
115
                                }
 
116
                                service.SaveConfiguration ();
 
117
                                return rr;
 
118
                        } catch (Exception ex) {
 
119
                                if (monitor != null)
 
120
                                        monitor.ReportError ("The repository could not be registered", ex);
 
121
                                if (ContainsRepository (url))
 
122
                                        RemoveRepository (url);
 
123
                                return null;
 
124
                        }
 
125
                }
 
126
                
 
127
                internal RepositoryRecord RegisterRepository (string url, bool isReference)
 
128
                {
 
129
                        RepositoryRecord rr = FindRepositoryRecord (url);
 
130
                        if (rr != null) {
 
131
                                if (rr.IsReference && !isReference) {
 
132
                                        rr.IsReference = false;
 
133
                                        service.SaveConfiguration ();
 
134
                                }
 
135
                                return rr;
 
136
                        }
 
137
                        
 
138
                        rr = new RepositoryRecord ();
 
139
                        rr.Url = url;
 
140
                        rr.IsReference = isReference;
 
141
                        
 
142
                        string name = service.RepositoryCachePath;
 
143
                        if (!Directory.Exists (name))
 
144
                                Directory.CreateDirectory (name);
 
145
                        string host = new Uri (url).Host;
 
146
                        if (host.Length == 0)
 
147
                                host = "repo";
 
148
                        name = Path.Combine (name, host);
 
149
                        rr.File = name + "_" + service.Configuration.RepositoryIdCount + ".mrep";
 
150
                        
 
151
                        rr.Id = "rep" + service.Configuration.RepositoryIdCount;
 
152
                        service.Configuration.Repositories.Add (rr);
 
153
                        service.Configuration.RepositoryIdCount++;
 
154
                        service.SaveConfiguration ();
 
155
                        repoList = null;
 
156
                        return rr;
 
157
                }
 
158
                
 
159
                internal RepositoryRecord FindRepositoryRecord (string url)
 
160
                {
 
161
                        foreach (RepositoryRecord rr in service.Configuration.Repositories)
 
162
                                if (rr.Url == url) return rr;
 
163
                        return null;
 
164
                }
 
165
                
 
166
                /// <summary>
 
167
                /// Removes an on-line repository subscription.
 
168
                /// </summary>
 
169
                /// <param name="url">
 
170
                /// URL of the repository.
 
171
                /// </param>
 
172
                public void RemoveRepository (string url)
 
173
                {
 
174
                        RepositoryRecord rep = FindRepositoryRecord (url);
 
175
                        if (rep == null)
 
176
                                return; // Nothing to do
 
177
                        
 
178
                        foreach (RepositoryRecord rr in service.Configuration.Repositories) {
 
179
                                if (rr == rep) continue;
 
180
                                Repository newRep = rr.GetCachedRepository ();
 
181
                                if (newRep == null) continue;
 
182
                                foreach (ReferenceRepositoryEntry re in newRep.Repositories) {
 
183
                                        if (re.Url == url) {
 
184
                                                // The repository can't be removed because there is another
 
185
                                                // repository depending on it. Just mark it as a reference.
 
186
                                                rep.IsReference = true;
 
187
                                                return;
 
188
                                        }
 
189
                                }
 
190
                        }
 
191
                        
 
192
                        // There are no other repositories referencing this one, so we can safely delete
 
193
                        
 
194
                        Repository delRep = rep.GetCachedRepository ();
 
195
                        service.Configuration.Repositories.Remove (rep);
 
196
                        rep.ClearCachedRepository ();
 
197
                        
 
198
                        if (delRep != null) {
 
199
                                foreach (ReferenceRepositoryEntry re in delRep.Repositories)
 
200
                                        RemoveRepository (new Uri (new Uri (url), re.Url).ToString ());
 
201
                        }
 
202
 
 
203
                        service.SaveConfiguration ();
 
204
                        repoList = null;
 
205
                }
 
206
                
 
207
                /// <summary>
 
208
                /// Enables or disables a repository
 
209
                /// </summary>
 
210
                /// <param name='url'>
 
211
                /// URL of the repository
 
212
                /// </param>
 
213
                /// <param name='enabled'>
 
214
                /// 'true' if the repository has to be enabled.
 
215
                /// </param>
 
216
                /// <remarks>
 
217
                /// Disabled repositories are ignored when calling UpdateAllRepositories.
 
218
                /// </remarks>
 
219
                public void SetRepositoryEnabled (string url, bool enabled)
 
220
                {
 
221
                        RepositoryRecord rep = FindRepositoryRecord (url);
 
222
                        if (rep == null)
 
223
                                return; // Nothing to do
 
224
                        rep.Enabled = enabled;
 
225
                        Repository crep = rep.GetCachedRepository ();
 
226
                        if (crep != null) {
 
227
                                foreach (RepositoryEntry re in crep.Repositories)
 
228
                                        SetRepositoryEnabled (new Uri (new Uri (url), re.Url).ToString (), enabled);
 
229
                        }
 
230
                                
 
231
                        service.SaveConfiguration ();
 
232
                }
 
233
                
 
234
                /// <summary>
 
235
                /// Checks if a repository is already subscribed.
 
236
                /// </summary>
 
237
                /// <param name="url">
 
238
                /// URL of the repository
 
239
                /// </param>
 
240
                /// <returns>
 
241
                /// True if the repository is already subscribed.
 
242
                /// </returns>
 
243
                public bool ContainsRepository (string url)
 
244
                {
 
245
                        return FindRepositoryRecord (url) != null;
 
246
                }
 
247
                
 
248
                ArrayList RepositoryList {
 
249
                        get {
 
250
                                if (repoList == null) {
 
251
                                        ArrayList list = new ArrayList ();
 
252
                                        foreach (RepositoryRecord rep in service.Configuration.Repositories) {
 
253
                                                if (!rep.IsReference)
 
254
                                                        list.Add (rep);
 
255
                                        }
 
256
                                        repoList = list;
 
257
                                }
 
258
                                return repoList;
 
259
                        }
 
260
                }
 
261
                
 
262
                /// <summary>
 
263
                /// Gets a list of subscribed repositories
 
264
                /// </summary>
 
265
                /// <returns>
 
266
                /// A list of repositories.
 
267
                /// </returns>
 
268
                public AddinRepository[] GetRepositories ()
 
269
                {
 
270
                        return (AddinRepository[]) RepositoryList.ToArray (typeof(AddinRepository));
 
271
                }
 
272
                                             
 
273
                /// <summary>
 
274
                /// Updates the add-in index of all subscribed repositories.
 
275
                /// </summary>
 
276
                /// <param name="monitor">
 
277
                /// Progress monitor where to show progress status and log
 
278
                /// </param>
 
279
                public void UpdateAllRepositories (IProgressStatus monitor)
 
280
                {
 
281
                        UpdateRepository (monitor, (string)null);
 
282
                }
 
283
                
 
284
                /// <summary>
 
285
                /// Updates the add-in index of the provided repository
 
286
                /// </summary>
 
287
                /// <param name="statusMonitor">
 
288
                /// Progress monitor where to show progress status and log
 
289
                /// </param>
 
290
                /// <param name="url">
 
291
                /// URL of the repository
 
292
                /// </param>
 
293
                public void UpdateRepository (IProgressStatus statusMonitor, string url)
 
294
                {
 
295
                        repoList = null;
 
296
                        
 
297
                        IProgressMonitor monitor = ProgressStatusMonitor.GetProgressMonitor (statusMonitor);
 
298
                
 
299
                        monitor.BeginTask ("Updating repositories", service.Configuration.Repositories.Count);
 
300
                        try {
 
301
                                int num = service.Configuration.Repositories.Count;
 
302
                                for (int n=0; n<num; n++) {
 
303
                                        RepositoryRecord rr = (RepositoryRecord) service.Configuration.Repositories [n];
 
304
                                        if (((url == null && rr.Enabled) || rr.Url == url) && !rr.IsReference)
 
305
                                                UpdateRepository (monitor, new Uri (rr.Url), rr);
 
306
                                        monitor.Step (1);
 
307
                                }
 
308
                        } catch (Exception ex) {
 
309
                                statusMonitor.ReportError ("Could not get information from repository", ex);
 
310
                                return;
 
311
                        } finally {
 
312
                                monitor.EndTask ();
 
313
                        }
 
314
                        service.SaveConfiguration ();
 
315
                }
 
316
 
 
317
                void UpdateRepository (IProgressMonitor monitor, Uri baseUri, RepositoryRecord rr)
 
318
                {
 
319
                        Uri absUri = new Uri (baseUri, rr.Url);
 
320
                        monitor.BeginTask ("Updating from " + absUri.ToString (), 2);
 
321
                        Repository newRep = null;
 
322
                        Exception error = null;
 
323
                        
 
324
                        try {
 
325
                                newRep = (Repository) service.Store.DownloadObject (monitor, absUri.ToString (), typeof(Repository));
 
326
                        } catch (Exception ex) {
 
327
                                error = ex;
 
328
                        }
 
329
                        
 
330
                        if (newRep == null) {
 
331
                                monitor.ReportError ("Could not get information from repository" + ": " + absUri.ToString (), error);
 
332
                                return;
 
333
                        }
 
334
                        
 
335
                        monitor.Step (1);
 
336
                        
 
337
                        foreach (ReferenceRepositoryEntry re in newRep.Repositories) {
 
338
                                Uri refRepUri = new Uri (absUri, re.Url);
 
339
                                string refRepUrl = refRepUri.ToString ();
 
340
                                RepositoryRecord refRep = FindRepositoryRecord (refRepUrl);
 
341
                                if (refRep == null)
 
342
                                        refRep = RegisterRepository (refRepUrl, true);
 
343
                                refRep.Enabled = rr.Enabled;
 
344
                                // Update the repo if the modified timestamp changes or if there is no timestamp info
 
345
                                if (refRep.LastModified != re.LastModified || re.LastModified == DateTime.MinValue) {
 
346
                                        refRep.LastModified = re.LastModified;
 
347
                                        UpdateRepository (monitor, refRepUri, refRep);
 
348
                                }
 
349
                        }
 
350
                        monitor.EndTask ();
 
351
                        rr.UpdateCachedRepository (newRep);
 
352
                }
 
353
                
 
354
                /// <summary>
 
355
                /// Gets a list of available add-in updates.
 
356
                /// </summary>
 
357
                /// <returns>
 
358
                /// A list of add-in references.
 
359
                /// </returns>
 
360
                /// <remarks>
 
361
                /// The list is generated by looking at the add-ins currently installed and checking if there is any
 
362
                /// add-in with a newer version number in any of the subscribed repositories. This method uses cached
 
363
                /// information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories
 
364
                /// before using this method to ensure that the latest information is available.
 
365
                /// </remarks>
 
366
                public AddinRepositoryEntry[] GetAvailableUpdates ()
 
367
                {
 
368
                        return GetAvailableAddin (null, null, null, true, RepositorySearchFlags.None);
 
369
                }
 
370
 
 
371
                /// <summary>
 
372
                /// Gets a list of available add-in updates.
 
373
                /// </summary>
 
374
                /// <param name="flags">
 
375
                /// Search flags
 
376
                /// </param>
 
377
                /// <returns>
 
378
                /// A list of add-in references.
 
379
                /// </returns>
 
380
                /// <remarks>
 
381
                /// The list is generated by looking at the add-ins currently installed and checking if there is any
 
382
                /// add-in with a newer version number in any of the subscribed repositories. This method uses cached
 
383
                /// information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories
 
384
                /// before using this method to ensure that the latest information is available.
 
385
                /// </remarks>
 
386
                public AddinRepositoryEntry[] GetAvailableUpdates (RepositorySearchFlags flags)
 
387
                {
 
388
                        return GetAvailableAddin (null, null, null, true, flags);
 
389
                }
 
390
 
 
391
                /// <summary>
 
392
                /// Gets a list of available add-in updates in a specific repository.
 
393
                /// </summary>
 
394
                /// <param name="repositoryUrl">
 
395
                /// The repository URL
 
396
                /// </param>
 
397
                /// <returns>
 
398
                /// A list of add-in references.
 
399
                /// </returns>
 
400
                /// <remarks>
 
401
                /// The list is generated by looking at the add-ins currently installed and checking if there is any
 
402
                /// add-in with a newer version number in the provided repository. This method uses cached
 
403
                /// information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories
 
404
                /// before using this method to ensure that the latest information is available.
 
405
                /// </remarks>
 
406
                public AddinRepositoryEntry[] GetAvailableUpdates (string repositoryUrl)
 
407
                {
 
408
                        return GetAvailableAddin (repositoryUrl, null, null, true, RepositorySearchFlags.None);
 
409
                }
 
410
                
 
411
#pragma warning disable 1591
 
412
                [Obsolete ("Use GetAvailableAddinUpdates (id) instead")]
 
413
                public AddinRepositoryEntry[] GetAvailableUpdates (string id, string version)
 
414
                {
 
415
                        return GetAvailableAddin (null, id, version, true, RepositorySearchFlags.None);
 
416
                }
 
417
                
 
418
                [Obsolete ("Use GetAvailableAddinUpdates (repositoryUrl, id) instead")]
 
419
                public AddinRepositoryEntry[] GetAvailableUpdates (string repositoryUrl, string id, string version)
 
420
                {
 
421
                        return GetAvailableAddin (repositoryUrl, id, version, true, RepositorySearchFlags.None);
 
422
                }
 
423
#pragma warning restore 1591
 
424
                
 
425
                /// <summary>
 
426
                /// Gets a list of available updates for an add-in.
 
427
                /// </summary>
 
428
                /// <param name="id">
 
429
                /// Identifier of the add-in.
 
430
                /// </param>
 
431
                /// <returns>
 
432
                /// List of updates for the specified add-in.
 
433
                /// </returns>
 
434
                /// <remarks>
 
435
                /// The list is generated by checking if there is any
 
436
                /// add-in with a newer version number in any of the subscribed repositories. This method uses cached
 
437
                /// information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories
 
438
                /// before using this method to ensure that the latest information is available.
 
439
                /// </remarks>
 
440
                public AddinRepositoryEntry[] GetAvailableAddinUpdates (string id)
 
441
                {
 
442
                        return GetAvailableAddin (null, id, null, true, RepositorySearchFlags.None);
 
443
                }
 
444
                
 
445
                /// <summary>
 
446
                /// Gets a list of available updates for an add-in.
 
447
                /// </summary>
 
448
                /// <param name="id">
 
449
                /// Identifier of the add-in.
 
450
                /// </param>
 
451
                /// <param name='flags'>
 
452
                /// Search flags.
 
453
                /// </param>
 
454
                /// <returns>
 
455
                /// List of updates for the specified add-in.
 
456
                /// </returns>
 
457
                /// <remarks>
 
458
                /// The list is generated by checking if there is any
 
459
                /// add-in with a newer version number in any of the subscribed repositories. This method uses cached
 
460
                /// information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories
 
461
                /// before using this method to ensure that the latest information is available.
 
462
                /// </remarks>
 
463
                public AddinRepositoryEntry[] GetAvailableAddinUpdates (string id, RepositorySearchFlags flags)
 
464
                {
 
465
                        return GetAvailableAddin (null, id, null, true, flags);
 
466
                }
 
467
                
 
468
                /// <summary>
 
469
                /// Gets a list of available updates for an add-in in a specific repository
 
470
                /// </summary>
 
471
                /// <param name="repositoryUrl">
 
472
                /// Identifier of the add-in.
 
473
                /// </param>
 
474
                /// <param name="id">
 
475
                /// Identifier of the add-in.
 
476
                /// </param>
 
477
                /// <returns>
 
478
                /// List of updates for the specified add-in.
 
479
                /// </returns>
 
480
                /// <remarks>
 
481
                /// The list is generated by checking if there is any
 
482
                /// add-in with a newer version number in the provided repository. This method uses cached
 
483
                /// information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories
 
484
                /// before using this method to ensure that the latest information is available.
 
485
                /// </remarks>
 
486
                public AddinRepositoryEntry[] GetAvailableAddinUpdates (string repositoryUrl, string id)
 
487
                {
 
488
                        return GetAvailableAddin (repositoryUrl, id, null, true, RepositorySearchFlags.None);
 
489
                }
 
490
                
 
491
                /// <summary>
 
492
                /// Gets a list of available updates for an add-in in a specific repository
 
493
                /// </summary>
 
494
                /// <param name="repositoryUrl">
 
495
                /// Identifier of the add-in.
 
496
                /// </param>
 
497
                /// <param name="id">
 
498
                /// Identifier of the add-in.
 
499
                /// </param>
 
500
                /// <param name='flags'>
 
501
                /// Search flags.
 
502
                /// </param>
 
503
                /// <returns>
 
504
                /// List of updates for the specified add-in.
 
505
                /// </returns>
 
506
                /// <remarks>
 
507
                /// The list is generated by checking if there is any
 
508
                /// add-in with a newer version number in the provided repository. This method uses cached
 
509
                /// information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories
 
510
                /// before using this method to ensure that the latest information is available.
 
511
                /// </remarks>
 
512
                public AddinRepositoryEntry[] GetAvailableAddinUpdates (string repositoryUrl, string id, RepositorySearchFlags flags)
 
513
                {
 
514
                        return GetAvailableAddin (repositoryUrl, id, null, true, flags);
 
515
                }
 
516
                
 
517
                /// <summary>
 
518
                /// Gets a list of all available add-ins
 
519
                /// </summary>
 
520
                /// <returns>
 
521
                /// A list of add-ins
 
522
                /// </returns>
 
523
                /// <remarks>
 
524
                /// This method uses cached
 
525
                /// information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories
 
526
                /// before using this method to ensure that the latest information is available.
 
527
                /// </remarks>
 
528
                public AddinRepositoryEntry[] GetAvailableAddins ()
 
529
                {
 
530
                        return GetAvailableAddin (null, null, null, false, RepositorySearchFlags.None);
 
531
                }
 
532
                
 
533
                /// <summary>
 
534
                /// Gets a list of all available add-ins
 
535
                /// </summary>
 
536
                /// <returns>
 
537
                /// The available addins.
 
538
                /// </returns>
 
539
                /// <param name='flags'>
 
540
                /// Search flags.
 
541
                /// </param>
 
542
                /// <remarks>
 
543
                /// This method uses cached
 
544
                /// information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories
 
545
                /// before using this method to ensure that the latest information is available.
 
546
                /// </remarks>
 
547
                public AddinRepositoryEntry[] GetAvailableAddins (RepositorySearchFlags flags)
 
548
                {
 
549
                        return GetAvailableAddin (null, null, null, false, flags);
 
550
                }
 
551
                
 
552
                /// <summary>
 
553
                /// Gets a list of all available add-ins in a repository
 
554
                /// </summary>
 
555
                /// <param name="repositoryUrl">
 
556
                /// A repository URL
 
557
                /// </param>
 
558
                /// <returns>
 
559
                /// A list of add-ins
 
560
                /// </returns>
 
561
                /// <remarks>
 
562
                /// This method uses cached
 
563
                /// information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories
 
564
                /// before using this method to ensure that the latest information is available.
 
565
                /// </remarks>
 
566
                public AddinRepositoryEntry[] GetAvailableAddins (string repositoryUrl)
 
567
                {
 
568
                        return GetAvailableAddin (repositoryUrl, null, null);
 
569
                }
 
570
                
 
571
                /// <summary>
 
572
                /// Gets a list of all available add-ins in a repository
 
573
                /// </summary>
 
574
                /// <param name="repositoryUrl">
 
575
                /// A repository URL
 
576
                /// </param>
 
577
                /// <param name='flags'>
 
578
                /// Search flags.
 
579
                /// </param>
 
580
                /// <returns>
 
581
                /// A list of add-ins
 
582
                /// </returns>
 
583
                /// <remarks>
 
584
                /// This method uses cached
 
585
                /// information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories
 
586
                /// before using this method to ensure that the latest information is available.
 
587
                /// </remarks>
 
588
                public AddinRepositoryEntry[] GetAvailableAddins (string repositoryUrl, RepositorySearchFlags flags)
 
589
                {
 
590
                        return GetAvailableAddin (repositoryUrl, null, null, false, flags);
 
591
                }
 
592
                
 
593
                /// <summary>
 
594
                /// Checks if an add-in is available to be installed
 
595
                /// </summary>
 
596
                /// <param name="id">
 
597
                /// Identifier of the add-in
 
598
                /// </param>
 
599
                /// <param name="version">
 
600
                /// Version of the add-in (optional, it can be null)
 
601
                /// </param>
 
602
                /// <returns>
 
603
                /// A list of add-ins
 
604
                /// </returns>
 
605
                /// <remarks>
 
606
                /// List of references to add-ins available in on-line repositories. This method uses cached
 
607
                /// information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories
 
608
                /// before using this method to ensure that the latest information is available.
 
609
                /// </remarks>
 
610
                public AddinRepositoryEntry[] GetAvailableAddin (string id, string version)
 
611
                {
 
612
                        return GetAvailableAddin (null, id, version);
 
613
                }
 
614
                
 
615
                /// <summary>
 
616
                /// Checks if an add-in is available to be installed from a repository
 
617
                /// </summary>
 
618
                /// <param name="repositoryUrl">
 
619
                /// A repository URL
 
620
                /// </param>
 
621
                /// <param name="id">
 
622
                /// Identifier of the add-in
 
623
                /// </param>
 
624
                /// <param name="version">
 
625
                /// Version of the add-in (optional, it can be null)
 
626
                /// </param>
 
627
                /// <returns>
 
628
                /// A list of add-ins
 
629
                /// </returns>
 
630
                /// <remarks>
 
631
                /// List of references to add-ins available in the repository. This method uses cached
 
632
                /// information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories
 
633
                /// before using this method to ensure that the latest information is available.
 
634
                /// </remarks>
 
635
                public AddinRepositoryEntry[] GetAvailableAddin (string repositoryUrl, string id, string version)
 
636
                {
 
637
                        return GetAvailableAddin (repositoryUrl, id, version, false, RepositorySearchFlags.None);
 
638
                }
 
639
                
 
640
                PackageRepositoryEntry[] GetAvailableAddin (string repositoryUrl, string id, string version, bool updates, RepositorySearchFlags flags)
 
641
                {
 
642
                        List<PackageRepositoryEntry> list = new List<PackageRepositoryEntry> ();
 
643
                        
 
644
                        IEnumerable ee;
 
645
                        if (repositoryUrl != null) {
 
646
                                ArrayList repos = new ArrayList ();
 
647
                                GetRepositoryTree (repositoryUrl, repos);
 
648
                                ee = repos;
 
649
                        } else
 
650
                                ee = service.Configuration.Repositories;
 
651
                        
 
652
                        foreach (RepositoryRecord rr in ee) {
 
653
                                if (!rr.Enabled)
 
654
                                        continue;
 
655
                                Repository rep = rr.GetCachedRepository();
 
656
                                if (rep == null) continue;
 
657
                                foreach (PackageRepositoryEntry addin in rep.Addins) {
 
658
                                        if ((id == null || Addin.GetIdName (addin.Addin.Id) == id) && (version == null || addin.Addin.Version == version)) {
 
659
                                                if (updates) {
 
660
                                                        Addin ainfo = service.Registry.GetAddin (Addin.GetIdName (addin.Addin.Id));
 
661
                                                        if (ainfo == null || Addin.CompareVersions (ainfo.Version, addin.Addin.Version) <= 0)
 
662
                                                                continue;
 
663
                                                }
 
664
                                                list.Add (addin);
 
665
                                        }
 
666
                                }
 
667
                        }
 
668
                        
 
669
                        if ((flags & RepositorySearchFlags.LatestVersionsOnly) != 0)
 
670
                                FilterOldVersions (list);
 
671
                        
 
672
                        // Old versions are returned first
 
673
                        list.Sort ();
 
674
                        return list.ToArray ();
 
675
                }
 
676
                
 
677
                void FilterOldVersions (List<PackageRepositoryEntry> addins)
 
678
                {
 
679
                        Dictionary<string,string> versions = new Dictionary<string, string> ();
 
680
                        foreach (PackageRepositoryEntry a in addins) {
 
681
                                string last;
 
682
                                string id, version;
 
683
                                Addin.GetIdParts (a.Addin.Id, out id, out version);
 
684
                                if (!versions.TryGetValue (id, out last) || Addin.CompareVersions (last, version) > 0)
 
685
                                        versions [id] = version;
 
686
                        }
 
687
                        for (int n=0; n<addins.Count; n++) {
 
688
                                PackageRepositoryEntry a = addins [n];
 
689
                                string id, version;
 
690
                                Addin.GetIdParts (a.Addin.Id, out id, out version);
 
691
                                if (versions [id] != version)
 
692
                                        addins.RemoveAt (n--);
 
693
                        }
 
694
                }
 
695
                
 
696
                void GetRepositoryTree (string url, ArrayList list)
 
697
                {
 
698
                        RepositoryRecord rr = FindRepositoryRecord (url);
 
699
                        if (rr == null) return;
 
700
                        
 
701
                        if (list.Contains (rr))
 
702
                                return;
 
703
                                
 
704
                        list.Add (rr);
 
705
                        Repository rep = rr.GetCachedRepository ();
 
706
                        if (rep == null)
 
707
                                return;
 
708
                        
 
709
                        Uri absUri = new Uri (url);
 
710
                        foreach (ReferenceRepositoryEntry re in rep.Repositories) {
 
711
                                Uri refRepUri = new Uri (absUri, re.Url);
 
712
                                GetRepositoryTree (refRepUri.ToString (), list);
 
713
                        }
 
714
                }
 
715
        }
 
716
        
 
717
        public enum RepositorySearchFlags
 
718
        {
 
719
                /// <summary>
 
720
                /// No special search options
 
721
                /// </summary>
 
722
                None,
 
723
                
 
724
                /// <summary>
 
725
                /// Only the latest version of every add-in is included in the search
 
726
                /// </summary>
 
727
                LatestVersionsOnly = 1,
 
728
        }
 
729
}