Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono-addins.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLluis Sanchez <llsan@microsoft.com>2018-02-26 20:22:21 +0300
committerLluis Sanchez <llsan@microsoft.com>2018-02-26 20:22:21 +0300
commit8dc3e7af0ba110f9a1832e365d8aa08d1e77ffd8 (patch)
treed9ddc5495448dd5dbc6dafae50cfa2b652108ff8 /Mono.Addins/Mono.Addins.Database/AssemblyLocatorVisitor.cs
parent3147dc5c2a2a147e95745a87d1a9d927f4fbf08d (diff)
Complete implementation of addin scan data file generation
Refactored the code to allow generating scan data files independently from the add-in database update process. The new AddinFolderVisitor class can be used to visit all the add-in folders. Split the functionality previously in AddinScanner in two classes. AddinRegistryUpdater is now in charge of locating the addins. AddinScanner now only implements the actual add-in scanning code, and the logic to setup a custom assembly resolver has moved there.
Diffstat (limited to 'Mono.Addins/Mono.Addins.Database/AssemblyLocatorVisitor.cs')
-rw-r--r--Mono.Addins/Mono.Addins.Database/AssemblyLocatorVisitor.cs127
1 files changed, 127 insertions, 0 deletions
diff --git a/Mono.Addins/Mono.Addins.Database/AssemblyLocatorVisitor.cs b/Mono.Addins/Mono.Addins.Database/AssemblyLocatorVisitor.cs
new file mode 100644
index 0000000..545b3be
--- /dev/null
+++ b/Mono.Addins/Mono.Addins.Database/AssemblyLocatorVisitor.cs
@@ -0,0 +1,127 @@
+//
+// AssemblyLocatorVisitor.cs
+//
+// Author:
+// Lluis Sanchez <llsan@microsoft.com>
+//
+// Copyright (c) 2018 Microsoft
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.IO;
+using System.Reflection;
+using System.Collections.Generic;
+
+namespace Mono.Addins.Database
+{
+ class AssemblyLocatorVisitor: AddinFolderVisitor, IAssemblyLocator
+ {
+ AddinRegistry registry;
+ AssemblyIndex index;
+ bool usePreScanDataFiles;
+
+ public AssemblyLocatorVisitor (AddinDatabase database, AddinRegistry registry, bool usePreScanDataFiles): base (database)
+ {
+ this.registry = registry;
+ this.usePreScanDataFiles = usePreScanDataFiles;
+ }
+
+ public string GetAssemblyLocation (string fullName)
+ {
+ if (index == null) {
+ index = new AssemblyIndex ();
+ if (registry.StartupDirectory != null)
+ VisitFolder (null, registry.StartupDirectory, null, false);
+ foreach (string dir in registry.GlobalAddinDirectories)
+ VisitFolder (null, dir, AddinDatabase.GlobalDomain, true);
+ }
+
+ return index.GetAssemblyLocation (fullName);
+ }
+
+ protected override void OnVisitFolder (IProgressStatus monitor, string path, string domain, bool recursive)
+ {
+ if (usePreScanDataFiles) {
+ var scanDataIndex = AddinScanDataIndex.LoadFromFolder (monitor, path);
+ if (scanDataIndex != null) {
+ foreach (var file in scanDataIndex.Assemblies)
+ index.AddAssemblyLocation (file);
+ return;
+ }
+ }
+ base.OnVisitFolder (monitor, path, domain, recursive);
+ }
+
+ protected override void OnVisitAssemblyFile (IProgressStatus monitor, string file)
+ {
+ index.AddAssemblyLocation (file);
+ }
+ }
+
+ class AssemblyIndex: IAssemblyLocator
+ {
+ Dictionary<string,List<string>> assemblyLocations = new Dictionary<string, List<string>> ();
+ Dictionary<string,string> assemblyLocationsByFullName = new Dictionary<string, string> ();
+
+ public void AddAssemblyLocation (string file)
+ {
+ string name = Path.GetFileNameWithoutExtension (file);
+ if (!assemblyLocations.TryGetValue (name, out var list)) {
+ list = new List<string> ();
+ assemblyLocations [name] = list;
+ }
+ list.Add (file);
+ }
+
+ public string GetAssemblyLocation (string fullName)
+ {
+ if (assemblyLocationsByFullName.TryGetValue (fullName, out var loc))
+ return loc;
+
+ int i = fullName.IndexOf (',');
+ string name = fullName.Substring (0, i);
+ if (name == "Mono.Addins")
+ return GetType ().Assembly.Location;
+
+ if (!assemblyLocations.TryGetValue (name, out var list))
+ return null;
+
+ string lastAsm = null;
+ foreach (string file in list.ToArray ()) {
+ try {
+ list.Remove (file);
+ AssemblyName aname = AssemblyName.GetAssemblyName (file);
+ lastAsm = file;
+ assemblyLocationsByFullName [aname.FullName] = file;
+ if (aname.FullName == fullName)
+ return file;
+ } catch {
+ // Could not get the assembly name. The file either doesn't exist or it is not a valid assembly.
+ // In this case, just ignore it.
+ }
+ }
+
+ if (lastAsm != null) {
+ // If an exact version is not found, just take any of them
+ return lastAsm;
+ }
+ return null;
+ }
+ }
+}