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:
-rw-r--r--Mono.Addins/ChangeLog24
-rw-r--r--Mono.Addins/Mono.Addins.Database/AddinDatabase.cs570
-rw-r--r--Mono.Addins/Mono.Addins.Database/AddinHostIndex.cs15
-rw-r--r--Mono.Addins/Mono.Addins.Database/AddinScanFolderInfo.cs82
-rw-r--r--Mono.Addins/Mono.Addins.Database/AddinScanner.cs132
-rw-r--r--Mono.Addins/Mono.Addins.Database/AddinUpdateData.cs277
-rw-r--r--Mono.Addins/Mono.Addins.Database/FileDatabase.cs24
-rw-r--r--Mono.Addins/Mono.Addins.Description/AddinDescription.cs41
-rw-r--r--Mono.Addins/Mono.Addins.Description/Extension.cs2
-rw-r--r--Mono.Addins/Mono.Addins.Description/ExtensionNodeSet.cs2
-rw-r--r--Mono.Addins/Mono.Addins.mdp1
-rw-r--r--Mono.Addins/Mono.Addins/Addin.cs30
-rw-r--r--Mono.Addins/Mono.Addins/AddinManager.cs10
-rw-r--r--Mono.Addins/Mono.Addins/AddinRegistry.cs37
-rw-r--r--Mono.Addins/Mono.Addins/AddinSessionService.cs2
15 files changed, 725 insertions, 524 deletions
diff --git a/Mono.Addins/ChangeLog b/Mono.Addins/ChangeLog
index 62d9251..b8927bf 100644
--- a/Mono.Addins/ChangeLog
+++ b/Mono.Addins/ChangeLog
@@ -1,5 +1,29 @@
2007-08-07 Lluis Sanchez Gual <lluis@novell.com>
+ * Mono.Addins.Database/AddinDatabase.cs,
+ Mono.Addins.Database/AddinHostIndex.cs,
+ Mono.Addins.Database/AddinScanFolderInfo.cs,
+ Mono.Addins.Database/AddinScanner.cs,
+ Mono.Addins.Database/AddinUpdateData.cs,
+ Mono.Addins.Database/FileDatabase.cs,
+ Mono.Addins.Description/AddinDescription.cs,
+ Mono.Addins.Description/Extension.cs,
+ Mono.Addins.Description/ExtensionNodeSet.cs, Mono.Addins.mdp,
+ Mono.Addins/Addin.cs, Mono.Addins/AddinManager.cs,
+ Mono.Addins/AddinRegistry.cs, Mono.Addins/AddinSessionService.cs:
+ Implemented support for non-shared add-in folders. Add-ins located in
+ such folders won't be visible from other non-shared folders. Folders
+ containing add-in hosts are non-shared by default, wihch means that
+ different installations of the same application won't interfere each
+ other anymore.
+
+ Add-in roots now can have depencencies on other add-in roots lacated in
+ the same folder.
+
+ The add-in database format has changed.
+
+2007-08-07 Lluis Sanchez Gual <lluis@novell.com>
+
* Mono.Addins/RuntimeAddin.cs: Added missing null check.
2007-07-27 Lluis Sanchez Gual <lluis@novell.com>
diff --git a/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs b/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs
index f02edcb..7a41492 100644
--- a/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs
+++ b/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs
@@ -40,9 +40,13 @@ namespace Mono.Addins.Database
{
class AddinDatabase
{
+ public const string GlobalDomain = "global";
+
const string VersionTag = "000";
+ ArrayList allSetupInfos;
ArrayList addinSetupInfos;
+ ArrayList rootSetupInfos;
internal static bool RunningSetupProcess;
bool fatalDatabseError;
Hashtable cachedAddinSetupInfos = new Hashtable ();
@@ -52,6 +56,7 @@ namespace Mono.Addins.Database
string addinDbDir;
DatabaseConfiguration config = null;
AddinRegistry registry;
+ int lastDomainId;
public AddinDatabase (AddinRegistry registry)
{
@@ -98,27 +103,19 @@ namespace Mono.Addins.Database
Directory.Delete (AddinFolderCachePath, true);
}
- public ExtensionNodeSet FindNodeSet (string addinId, string id)
+ public ExtensionNodeSet FindNodeSet (string domain, string addinId, string id)
{
- return FindNodeSet (addinId, id, new Hashtable ());
+ return FindNodeSet (domain, addinId, id, new Hashtable ());
}
- ExtensionNodeSet FindNodeSet (string addinId, string id, Hashtable visited)
+ ExtensionNodeSet FindNodeSet (string domain, string addinId, string id, Hashtable visited)
{
if (visited.Contains (addinId))
return null;
visited.Add (addinId, addinId);
- Addin addin = GetInstalledAddin (addinId, true, false);
- if (addin == null) {
- foreach (Addin root in GetAddinRoots ()) {
- if (root.Id == addinId) {
- addin = root;
- break;
- }
- }
- if (addin == null)
- return null;
- }
+ Addin addin = GetInstalledAddin (domain, addinId, true, false);
+ if (addin == null)
+ return null;
AddinDescription desc = addin.Description;
if (desc == null)
return null;
@@ -133,78 +130,128 @@ namespace Mono.Addins.Database
if (adep == null) continue;
string aid = Addin.GetFullId (desc.Namespace, adep.AddinId, adep.Version);
- ExtensionNodeSet nset = FindNodeSet (aid, id, visited);
+ ExtensionNodeSet nset = FindNodeSet (domain, aid, id, visited);
if (nset != null)
return nset;
}
return null;
}
- public AddinDescription GetDescription (string id)
+ public ArrayList GetInstalledAddins (string domain, AddinType type)
{
- InternalCheck ();
- IDisposable dblock = fileDatabase.LockRead ();
- try {
- string path = GetDescriptionPath (id);
- AddinDescription desc = AddinDescription.ReadBinary (fileDatabase, path);
- if (desc != null)
- desc.OwnerDatabase = this;
- return desc;
+ if (type == AddinType.All) {
+ if (allSetupInfos != null)
+ return allSetupInfos;
}
- catch (FileNotFoundException) {
- throw new InvalidOperationException ("Add-in not found: " + id);
- } finally {
- dblock.Dispose ();
+ else if (type == AddinType.Addin) {
+ if (addinSetupInfos != null)
+ return addinSetupInfos;
+ }
+ else {
+ if (rootSetupInfos != null)
+ return rootSetupInfos;
}
- }
- public ArrayList GetInstalledAddins ()
- {
- if (addinSetupInfos != null)
- return addinSetupInfos;
+ InternalCheck (domain);
- InternalCheck ();
using (fileDatabase.LockRead ()) {
- return InternalGetInstalledAddins ();
+ return InternalGetInstalledAddins (domain, null, type);
}
}
- public ArrayList GetAddinRoots ()
+ ArrayList InternalGetInstalledAddins (string domain, AddinType type)
{
- ArrayList list = new ArrayList ();
- foreach (string file in fileDatabase.GetDirectoryFiles (AddinCachePath, "*.mroot")) {
- list.Add (new Addin (this, file));
+ return InternalGetInstalledAddins (domain, null, type);
+ }
+
+ ArrayList InternalGetInstalledAddins (string domain, string idFilter, AddinType type)
+ {
+ if (allSetupInfos == null) {
+ ArrayList alist = new ArrayList ();
+
+ // Global add-ins are valid for any private domain
+ if (domain != AddinDatabase.GlobalDomain)
+ FindInstalledAddins (alist, AddinDatabase.GlobalDomain, idFilter);
+
+ FindInstalledAddins (alist, domain, idFilter);
+ if (idFilter != null)
+ return alist;
+ allSetupInfos = alist;
+ }
+ if (type == AddinType.All)
+ return FilterById (allSetupInfos, idFilter);
+
+ if (type == AddinType.Addin) {
+ if (addinSetupInfos == null) {
+ addinSetupInfos = new ArrayList ();
+ foreach (Addin adn in allSetupInfos)
+ if (!adn.Description.IsRoot)
+ addinSetupInfos.Add (adn);
+ }
+ return FilterById (addinSetupInfos, idFilter);
+ }
+ else {
+ if (rootSetupInfos == null) {
+ rootSetupInfos = new ArrayList ();
+ foreach (Addin adn in allSetupInfos)
+ if (!adn.Description.IsRoot)
+ rootSetupInfos.Add (adn);
+ }
+ return FilterById (rootSetupInfos, idFilter);
}
- return list;
}
- ArrayList InternalGetInstalledAddins ()
+ ArrayList FilterById (ArrayList addins, string id)
{
- if (addinSetupInfos != null)
- return addinSetupInfos;
+ if (id == null)
+ return addins;
+ ArrayList list = new ArrayList ();
+ foreach (Addin adn in addins) {
+ if (Addin.GetIdName (adn.Id) == id)
+ list.Add (adn);
+ }
+ return list;
+ }
- addinSetupInfos = new ArrayList ();
-
- foreach (string file in fileDatabase.GetDirectoryFiles (AddinCachePath, "*.maddin")) {
- addinSetupInfos.Add (new Addin (this, file));
+ void FindInstalledAddins (ArrayList result, string domain, string idFilter)
+ {
+ if (idFilter == null) idFilter = "*";
+ string dir = Path.Combine (AddinCachePath, domain);
+ if (Directory.Exists (dir)) {
+ foreach (string file in fileDatabase.GetDirectoryFiles (dir, idFilter + ".maddin")) {
+ string id = Path.GetFileNameWithoutExtension (file);
+ result.Add (GetInstalledDomainAddin (domain, id, true, false, false));
+ }
}
- return addinSetupInfos;
+ }
+
+ public Addin GetInstalledAddin (string domain, string id)
+ {
+ return GetInstalledAddin (domain, id, false, false);
}
- public Addin GetInstalledAddin (string id)
+ public Addin GetInstalledAddin (string domain, string id, bool exactVersionMatch)
{
- return GetInstalledAddin (id, false, false);
+ return GetInstalledAddin (domain, id, exactVersionMatch, false);
}
- public Addin GetInstalledAddin (string id, bool exactVersionMatch)
+ public Addin GetInstalledAddin (string domain, string id, bool exactVersionMatch, bool enabledOnly)
{
- return GetInstalledAddin (id, exactVersionMatch, false);
+ // Try the given domain, and if not found, try the shared domain
+ Addin ad = GetInstalledDomainAddin (domain, id, exactVersionMatch, enabledOnly, true);
+ if (ad != null)
+ return ad;
+ if (domain != AddinDatabase.GlobalDomain)
+ return GetInstalledDomainAddin (AddinDatabase.GlobalDomain, id, exactVersionMatch, enabledOnly, true);
+ else
+ return null;
}
- public Addin GetInstalledAddin (string id, bool exactVersionMatch, bool enabledOnly)
+ Addin GetInstalledDomainAddin (string domain, string id, bool exactVersionMatch, bool enabledOnly, bool dbLockCheck)
{
Addin sinfo = null;
- object ob = cachedAddinSetupInfos [id];
+ string idd = id + " " + domain;
+ object ob = cachedAddinSetupInfos [idd];
if (ob != null) {
sinfo = ob as Addin;
if (sinfo != null) {
@@ -218,19 +265,20 @@ namespace Mono.Addins.Database
return null;
}
- InternalCheck ();
+ if (dbLockCheck)
+ InternalCheck (domain);
- using (fileDatabase.LockRead ())
+ using (dbLockCheck ? fileDatabase.LockRead () : null)
{
- string path = GetDescriptionPath (id);
+ string path = GetDescriptionPath (domain, id);
if (sinfo == null && fileDatabase.Exists (path)) {
sinfo = new Addin (this, path);
- cachedAddinSetupInfos [id] = sinfo;
+ cachedAddinSetupInfos [idd] = sinfo;
if (!enabledOnly || sinfo.Enabled)
return sinfo;
if (exactVersionMatch) {
// Cache lookups with negative result
- cachedAddinSetupInfos [id] = this;
+ cachedAddinSetupInfos [idd] = this;
return null;
}
}
@@ -241,11 +289,9 @@ namespace Mono.Addins.Database
string version, name, bestVersion = null;
Addin.GetIdParts (id, out name, out version);
- // FIXME: Not very efficient, will load all descriptions
- foreach (Addin ia in InternalGetInstalledAddins ())
+ foreach (Addin ia in InternalGetInstalledAddins (domain, name, AddinType.All))
{
- if (Addin.GetIdName (ia.Id) == name &&
- (!enabledOnly || ia.Enabled) &&
+ if ((!enabledOnly || ia.Enabled) &&
(version.Length == 0 || ia.SupportsVersion (version)) &&
(bestVersion == null || Addin.CompareVersions (bestVersion, ia.Version) > 0))
{
@@ -254,7 +300,7 @@ namespace Mono.Addins.Database
}
}
if (sinfo != null) {
- cachedAddinSetupInfos [id] = sinfo;
+ cachedAddinSetupInfos [idd] = sinfo;
return sinfo;
}
}
@@ -262,82 +308,81 @@ namespace Mono.Addins.Database
// Cache lookups with negative result
// Ignore the 'not installed' flag when disabled add-ins are allowed
if (enabledOnly)
- cachedAddinSetupInfos [id] = this;
+ cachedAddinSetupInfos [idd] = this;
return null;
}
}
- public Addin GetInstalledAddin (string id, string version)
+/* public Addin GetInstalledAddin (string domain, string id, string version)
{
- foreach (Addin ia in GetInstalledAddins ()) {
+ foreach (Addin ia in GetInstalledAddins (domain)) {
if ((id == null || ia.Id == id) && (version == null || ia.Version == version))
return ia;
}
return null;
}
-
+*/
public void Shutdown ()
{
- addinSetupInfos = null;
+ ResetCachedData ();
}
- public Addin GetAddinForHostAssembly (string assemblyLocation)
+ public Addin GetAddinForHostAssembly (string domain, string assemblyLocation)
{
- InternalCheck ();
+ InternalCheck (domain);
Addin ainfo = null;
object ob = cachedAddinSetupInfos [assemblyLocation];
- if (ob != null) {
- ainfo = ob as Addin;
- if (ainfo != null)
- return ainfo;
- else
- return null;
- }
+ if (ob != null)
+ return ob as Addin; // Don't use a cast here is ob may not be an Addin.
AddinHostIndex index = GetAddinHostIndex ();
- string addin, addinFile;
- if (index.GetAddinForAssembly (assemblyLocation, out addin, out addinFile)) {
- ainfo = new Addin (this, addin, addinFile);
+ string addin, addinFile, rdomain;
+ if (index.GetAddinForAssembly (assemblyLocation, out addin, out addinFile, out rdomain)) {
+ string sid = addin + " " + rdomain;
+ ainfo = cachedAddinSetupInfos [sid] as Addin;
+ if (ainfo == null)
+ ainfo = new Addin (this, GetDescriptionPath (rdomain, addin));
cachedAddinSetupInfos [assemblyLocation] = ainfo;
+ cachedAddinSetupInfos [addin + " " + rdomain] = ainfo;
}
return ainfo;
}
- public bool IsAddinEnabled (string id)
+ public bool IsAddinEnabled (string domain, string id)
{
- Addin ainfo = GetInstalledAddin (id);
+ Addin ainfo = GetInstalledAddin (domain, id);
if (ainfo != null)
return ainfo.Enabled;
else
return false;
}
- internal bool IsAddinEnabled (string id, bool exactVersionMatch)
+ internal bool IsAddinEnabled (string domain, string id, bool exactVersionMatch)
{
if (!exactVersionMatch)
- return IsAddinEnabled (id);
- Addin ainfo = GetInstalledAddin (id, exactVersionMatch, false);
+ return IsAddinEnabled (domain, id);
+ Addin ainfo = GetInstalledAddin (domain, id, exactVersionMatch, false);
if (ainfo == null)
return false;
return Configuration.IsEnabled (id, ainfo.AddinInfo.EnabledByDefault);
}
- public void EnableAddin (string id)
+ public void EnableAddin (string domain, string id)
{
- EnableAddin (id, true);
+ EnableAddin (domain, id, true);
}
- internal void EnableAddin (string id, bool exactVersionMatch)
+ internal void EnableAddin (string domain, string id, bool exactVersionMatch)
{
- Addin ainfo = GetInstalledAddin (id, exactVersionMatch, false);
+ Addin ainfo = GetInstalledAddin (domain, id, exactVersionMatch, false);
if (ainfo == null)
// It may be an add-in root
return;
- if (IsAddinEnabled (id))
+ if (IsAddinEnabled (domain, id))
return;
// Enable required add-ins
@@ -346,7 +391,7 @@ namespace Mono.Addins.Database
if (dep is AddinDependency) {
AddinDependency adep = dep as AddinDependency;
string adepid = Addin.GetFullId (ainfo.AddinInfo.Namespace, adep.AddinId, adep.Version);
- EnableAddin (adepid, false);
+ EnableAddin (domain, adepid, false);
}
}
@@ -357,13 +402,13 @@ namespace Mono.Addins.Database
AddinManager.SessionService.ActivateAddin (id);
}
- public void DisableAddin (string id)
+ public void DisableAddin (string domain, string id)
{
- Addin ai = GetInstalledAddin (id, true);
+ Addin ai = GetInstalledAddin (domain, id, true);
if (ai == null)
throw new InvalidOperationException ("Add-in '" + id + "' not installed.");
- if (!IsAddinEnabled (id))
+ if (!IsAddinEnabled (domain, id))
return;
Configuration.SetStatus (id, false, ai.AddinInfo.EnabledByDefault);
@@ -374,7 +419,7 @@ namespace Mono.Addins.Database
try {
string idName = Addin.GetIdName (id);
- foreach (Addin ainfo in GetInstalledAddins ()) {
+ foreach (Addin ainfo in GetInstalledAddins (domain, AddinType.Addin)) {
foreach (Dependency dep in ainfo.AddinInfo.Dependencies) {
AddinDependency adep = dep as AddinDependency;
if (adep == null)
@@ -388,10 +433,10 @@ namespace Mono.Addins.Database
// if there is an older version available. Check it now.
adepid = Addin.GetFullId (ainfo.AddinInfo.Namespace, adep.AddinId, adep.Version);
- Addin adepinfo = GetInstalledAddin (adepid, false, true);
+ Addin adepinfo = GetInstalledAddin (domain, adepid, false, true);
if (adepinfo == null) {
- DisableAddin (ainfo.Id);
+ DisableAddin (domain, ainfo.Id);
break;
}
}
@@ -408,12 +453,12 @@ namespace Mono.Addins.Database
AddinManager.SessionService.UnloadAddin (id);
}
- internal string GetDescriptionPath (string id)
+ internal string GetDescriptionPath (string domain, string id)
{
- return Path.Combine (AddinCachePath, id + ".maddin");
+ return Path.Combine (Path.Combine (AddinCachePath, domain), id + ".maddin");
}
- void InternalCheck ()
+ void InternalCheck (string domain)
{
// If the database is broken, don't try to regenerate it at every check.
if (fatalDatabseError)
@@ -426,19 +471,19 @@ namespace Mono.Addins.Database
}
}
if (update)
- Update (null);
+ Update (null, domain);
}
void GenerateAddinExtensionMapsInternal (IProgressStatus monitor, ArrayList addinsToUpdate, ArrayList removedAddins)
{
- AddinUpdateData updateData = new AddinUpdateData (this);
+ AddinUpdateData updateData = new AddinUpdateData (this, monitor);
// Clear cached data
cachedAddinSetupInfos.Clear ();
// Collect all information
- Hashtable addinHash = new Hashtable ();
+ AddinIndex addinHash = new AddinIndex ();
if (monitor.LogLevel > 1)
monitor.Log ("Generating add-in extension maps");
@@ -448,6 +493,7 @@ namespace Mono.Addins.Database
ArrayList files = new ArrayList ();
bool partialGeneration = addinsToUpdate != null;
+ string[] domains = GetDomains ();
// Get the files to be updated
@@ -455,18 +501,21 @@ namespace Mono.Addins.Database
changedAddins = new Hashtable ();
foreach (string s in addinsToUpdate) {
changedAddins [s] = s;
- string mp = GetDescriptionPath (s);
- if (fileDatabase.Exists (mp))
- files.Add (mp);
- else
- files.AddRange (fileDatabase.GetObjectSharedFiles (this.AddinCachePath, s, ".mroot"));
+
+ // Look for the add-in in any of the existing folders
+ foreach (string domain in domains) {
+ string mp = GetDescriptionPath (domain, s);
+ if (fileDatabase.Exists (mp)) {
+ files.Add (mp);
+ }
+ }
}
foreach (string s in removedAddins)
changedAddins [s] = s;
}
else {
- files.AddRange (fileDatabase.GetDirectoryFiles (AddinCachePath, "*.maddin"));
- files.AddRange (fileDatabase.GetDirectoryFiles (AddinCachePath, "*.mroot"));
+ foreach (string dom in domains)
+ files.AddRange (fileDatabase.GetDirectoryFiles (Path.Combine (AddinCachePath, dom), "*.maddin"));
}
// Load the descriptions.
@@ -490,40 +539,20 @@ namespace Mono.Addins.Database
conf.UnmergeExternalData (changedAddins);
descriptionsToSave.Add (conf);
- // Register extension points and node sets from root add-ins
- if (conf.IsRoot) {
- foreach (ExtensionPoint ep in conf.ExtensionPoints)
- updateData.RegisterAddinRootExtensionPoint (conf, ep);
- foreach (ExtensionNodeSet ns in conf.ExtensionNodeSets)
- updateData.RegisterAddinRootNodeSet (conf, ns);
- }
- else
- addinHash [conf.AddinId] = conf;
+ addinHash.Add (conf);
}
+
+ // Sort the add-ins, to make sure add-ins are processed before
+ // all their dependencies
+ ArrayList sorted = addinHash.GetSortedAddins ();
+
+ // Register extension points and node sets
+ foreach (AddinDescription conf in sorted)
+ CollectExtensionPointData (conf, updateData);
- foreach (AddinDescription conf in addinHash.Values) {
+ // Register extensions
+ foreach (AddinDescription conf in sorted)
CollectExtensionData (conf, updateData);
- }
-
- updateData.ResolveExtensions (monitor, addinHash);
-
- // Update the extension points defined by this add-in
- foreach (ExtensionPoint ep in updateData.GetUnresolvedExtensionPoints ()) {
- AddinDescription am = (AddinDescription) addinHash [ep.RootAddin];
- ExtensionPoint amep = am.ExtensionPoints [ep.Path];
- if (amep != null) {
- amep.MergeWith (am.AddinId, ep);
- amep.RootAddin = ep.RootAddin;
- }
- }
-
- // Now update the node sets
- foreach (ExtensionPoint ep in updateData.GetUnresolvedExtensionSets ()) {
- AddinDescription am = (AddinDescription) addinHash [ep.RootAddin];
- ExtensionNodeSet nset = am.ExtensionNodeSets [ep.Path];
- if (nset != null)
- nset.MergeWith (am.AddinId, ep.NodeSet);
- }
// Save the maps
foreach (AddinDescription conf in descriptionsToSave)
@@ -542,7 +571,7 @@ namespace Mono.Addins.Database
// Collects extension data in a hash table. The key is the path, the value is a list
// of add-ins ids that extend that path
- void CollectExtensionData (AddinDescription conf, AddinUpdateData updateData)
+ void CollectExtensionPointData (AddinDescription conf, AddinUpdateData updateData)
{
foreach (ExtensionNodeSet nset in conf.ExtensionNodeSets) {
try {
@@ -561,7 +590,10 @@ namespace Mono.Addins.Database
throw new InvalidOperationException ("Error reading extension point: " + ep.Path, ex);
}
}
-
+ }
+
+ void CollectExtensionData (AddinDescription conf, AddinUpdateData updateData)
+ {
foreach (ModuleDescription module in conf.AllModules) {
foreach (Extension ext in module.Extensions) {
updateData.RelExtensions++;
@@ -586,18 +618,50 @@ namespace Mono.Addins.Database
AddChildExtensions (conf, module, updateData, path + "/" + id, node.ChildNodes, node.NodeName == "Condition");
}
}
+
+ string[] GetDomains ()
+ {
+ string[] dirs = fileDatabase.GetDirectories (AddinCachePath);
+ string[] ids = new string [dirs.Length];
+ for (int n=0; n<dirs.Length; n++)
+ ids [n] = Path.GetFileName (dirs [n]);
+ return ids;
+ }
+ public string GetUniqueDomainId ()
+ {
+ if (lastDomainId != 0) {
+ lastDomainId++;
+ return lastDomainId.ToString ();
+ }
+ lastDomainId = 1;
+ foreach (string s in fileDatabase.GetDirectories (AddinCachePath)) {
+ string dn = Path.GetFileName (s);
+ if (dn == GlobalDomain)
+ continue;
+ try {
+ int n = int.Parse (dn);
+ if (n >= lastDomainId)
+ lastDomainId = n + 1;
+ } catch {
+ }
+ }
+ return lastDomainId.ToString ();
+ }
+
internal void ResetCachedData ()
{
+ allSetupInfos = null;
addinSetupInfos = null;
+ rootSetupInfos = null;
hostIndex = null;
cachedAddinSetupInfos.Clear ();
}
- public bool AddinDependsOn (string id1, string id2)
+ public bool AddinDependsOn (string domain, string id1, string id2)
{
- Addin addin1 = GetInstalledAddin (id1, false);
+ Addin addin1 = GetInstalledAddin (domain, id1, false);
// We can assumbe that if the add-in is not returned here, it may be a root addin.
if (addin1 == null)
@@ -611,13 +675,13 @@ namespace Mono.Addins.Database
string depid = Addin.GetFullId (addin1.AddinInfo.Namespace, adep.AddinId, null);
if (depid == id2)
return true;
- else if (AddinDependsOn (depid, id2))
+ else if (AddinDependsOn (domain, depid, id2))
return true;
}
return false;
}
- public void Repair (IProgressStatus monitor)
+ public void Repair (IProgressStatus monitor, string domain)
{
using (fileDatabase.LockWrite ()) {
try {
@@ -632,10 +696,10 @@ namespace Mono.Addins.Database
monitor.ReportError ("The add-in registry could not be rebuilt. It may be due to lack of write permissions to the directory: " + AddinDbDir, ex);
}
}
- Update (monitor);
+ Update (monitor, domain);
}
- public void Update (IProgressStatus monitor)
+ public void Update (IProgressStatus monitor, string domain)
{
if (monitor == null)
monitor = new ConsoleProgressStatus (false);
@@ -660,9 +724,11 @@ namespace Mono.Addins.Database
// Something has changed, the add-ins need to be re-scanned, but it has
// to be done in an external process
- using (fileDatabase.LockRead ()) {
- foreach (Addin ainfo in InternalGetInstalledAddins ()) {
- installed [ainfo.Id] = ainfo.Id;
+ if (domain != null) {
+ using (fileDatabase.LockRead ()) {
+ foreach (Addin ainfo in InternalGetInstalledAddins (domain, AddinType.Addin)) {
+ installed [ainfo.Id] = ainfo.Id;
+ }
}
}
@@ -675,9 +741,9 @@ namespace Mono.Addins.Database
monitor.ReportError ("The add-in database could not be updated. It may be due to file corruption. Try running the setup repair utility", null);
// Update the currently loaded add-ins
- if (changesFound && AddinManager.IsInitialized && AddinManager.Registry.RegistryPath == registry.RegistryPath) {
+ if (changesFound && domain != null && AddinManager.IsInitialized && AddinManager.Registry.RegistryPath == registry.RegistryPath) {
Hashtable newInstalled = new Hashtable ();
- foreach (Addin ainfo in GetInstalledAddins ()) {
+ foreach (Addin ainfo in GetInstalledAddins (domain, AddinType.Addin)) {
newInstalled [ainfo.Id] = ainfo.Id;
}
@@ -894,9 +960,9 @@ namespace Mono.Addins.Database
foreach (string dir in registry.AddinDirectories) {
if (dir == registry.DefaultAddinsFolder)
- scanner.ScanFolderRec (monitor, dir, scanResult);
+ scanner.ScanFolderRec (monitor, dir, GlobalDomain, scanResult);
else
- scanner.ScanFolder (monitor, dir, scanResult);
+ scanner.ScanFolder (monitor, dir, GlobalDomain, scanResult);
if (scanResult.CheckOnly) {
if (scanResult.ChangesFound || monitor.IsCanceled)
return;
@@ -961,12 +1027,9 @@ namespace Mono.Addins.Database
AddinScanFolderInfo finfo;
if (GetFolderInfoForPath (progressStatus, Path.GetDirectoryName (file), out finfo) && finfo != null) {
AddinFileInfo afi = finfo.GetAddinFileInfo (file);
- if (afi != null && afi.AddinId != null) {
+ if (afi != null && afi.IsAddin) {
AddinDescription adesc;
- if (afi.IsRoot)
- GetHostDescription (progressStatus, afi.AddinId, file, out adesc);
- else
- GetAddinDescription (progressStatus, afi.AddinId, out adesc);
+ GetAddinDescription (progressStatus, afi.Domain, afi.AddinId, out adesc);
if (adesc != null)
adesc.Save (outFile);
return;
@@ -996,6 +1059,15 @@ namespace Mono.Addins.Database
}
}
+ public string GetFolderDomain (IProgressStatus progressStatus, string path)
+ {
+ AddinScanFolderInfo folderInfo;
+ if (GetFolderInfoForPath (progressStatus, path, out folderInfo) && folderInfo != null && !folderInfo.SharedFolder)
+ return folderInfo.Domain;
+ else
+ return GlobalDomain;
+ }
+
Assembly OnResolveAddinAssembly (object s, ResolveEventArgs args)
{
string file = currentScanResult.GetAssemblyLocation (args.Name);
@@ -1019,23 +1091,13 @@ namespace Mono.Addins.Database
return Path.Combine (AddinFolderCachePath, s + ".data");
}
- internal void UninstallAddin (IProgressStatus monitor, string addinId, AddinScanResult scanResult)
+ internal void UninstallAddin (IProgressStatus monitor, string domain, string addinId, AddinScanResult scanResult)
{
scanResult.AddRemovedAddin (addinId);
- string file = GetDescriptionPath (addinId);
- DeleteAddin (monitor, file, scanResult);
- }
-
- internal void UninstallRootAddin (IProgressStatus monitor, string addinId, string addinFile, AddinScanResult scanResult)
- {
- string file = fileDatabase.GetSharedObjectFile (AddinCachePath, addinId, ".mroot", addinFile);
- DeleteAddin (monitor, file, scanResult);
- }
-
- void DeleteAddin (IProgressStatus monitor, string file, AddinScanResult scanResult)
- {
- if (!fileDatabase.Exists (file))
+ string file = GetDescriptionPath (domain, addinId);
+ if (!fileDatabase.Exists (file)) {
return;
+ }
// Add-in already existed. The dependencies of the old add-in need to be re-analized
@@ -1049,29 +1111,15 @@ namespace Mono.Addins.Database
scanResult.RegenerateRelationData = true;
SafeDelete (monitor, file);
+ string dir = Path.GetDirectoryName (file);
+ if (fileDatabase.DirectoryIsEmpty (dir))
+ SafeDeleteDir (monitor, dir);
SafeDeleteDir (monitor, Path.Combine (AddinPrivateDataPath, Path.GetFileNameWithoutExtension (file)));
}
- public bool GetHostDescription (IProgressStatus monitor, string addinId, string fileName, out AddinDescription description)
- {
- try {
- description = AddinDescription.ReadHostBinary (fileDatabase, AddinCachePath, addinId, fileName);
- if (description != null)
- description.OwnerDatabase = this;
- return true;
- }
- catch (Exception ex) {
- if (monitor == null)
- throw;
- description = null;
- monitor.ReportError ("Could not read folder info file", ex);
- return false;
- }
- }
-
- public bool GetAddinDescription (IProgressStatus monitor, string addinId, out AddinDescription description)
+ public bool GetAddinDescription (IProgressStatus monitor, string domain, string addinId, out AddinDescription description)
{
- string file = GetDescriptionPath (addinId);
+ string file = GetDescriptionPath (domain, addinId);
return ReadAddinDescription (monitor, file, out description);
}
@@ -1097,10 +1145,13 @@ namespace Mono.Addins.Database
try {
if (replaceFileName != null)
desc.SaveBinary (fileDatabase, replaceFileName);
- else if (desc.IsRoot)
- desc.SaveHostBinary (fileDatabase, AddinCachePath);
- else
- desc.SaveBinary (fileDatabase, GetDescriptionPath (desc.AddinId));
+ else {
+ string file = GetDescriptionPath (desc.Domain, desc.AddinId);
+ string dir = Path.GetDirectoryName (file);
+ if (!fileDatabase.DirExists (dir))
+ fileDatabase.CreateDir (dir);
+ desc.SaveBinary (fileDatabase, file);
+ }
return true;
}
catch (Exception ex) {
@@ -1109,14 +1160,10 @@ namespace Mono.Addins.Database
}
}
- public bool AddinDescriptionExists (string addinId)
- {
- return fileDatabase.Exists (GetDescriptionPath (addinId));
- }
-
- public bool HostDescriptionExists (string addinId, string sourceFile)
+ public bool AddinDescriptionExists (string domain, string addinId)
{
- return fileDatabase.SharedObjectExists (AddinCachePath, addinId, ".mroot", sourceFile);
+ string file = GetDescriptionPath (domain, addinId);
+ return fileDatabase.Exists (file);
}
public bool ReadFolderInfo (IProgressStatus monitor, string file, out AddinScanFolderInfo folderInfo)
@@ -1140,7 +1187,8 @@ namespace Mono.Addins.Database
}
catch (Exception ex) {
folderInfo = null;
- monitor.ReportError ("Could not read folder info file", ex);
+ if (monitor != null)
+ monitor.ReportError ("Could not read folder info file", ex);
return false;
}
}
@@ -1227,7 +1275,7 @@ namespace Mono.Addins.Database
return name;
int n = 1;
- while (fileDatabase.Exists (GetDescriptionPath (id))) {
+ while (AddinIdExists (id)) {
name = baseId + "_" + n;
id = Addin.GetFullId (ns, name, version);
n++;
@@ -1235,6 +1283,15 @@ namespace Mono.Addins.Database
return name;
}
+ bool AddinIdExists (string id)
+ {
+ foreach (string d in fileDatabase.GetDirectories (AddinCachePath)) {
+ if (fileDatabase.Exists (Path.Combine (d, id + ".addin")))
+ return true;
+ }
+ return false;
+ }
+
public void ResetConfiguration ()
{
if (File.Exists (ConfigFile))
@@ -1286,7 +1343,7 @@ namespace Mono.Addins.Database
scanResult.LocateAssembliesOnly = true;
foreach (string dir in registry.AddinDirectories)
- scanner.ScanFolder (progressStatus, dir, scanResult);
+ scanner.ScanFolder (progressStatus, dir, AddinDatabase.GlobalDomain, scanResult);
}
string afile = scanResult.GetAssemblyLocation (args.Name);
@@ -1296,6 +1353,101 @@ namespace Mono.Addins.Database
return null;
}
}
+
+ class AddinIndex
+ {
+ Hashtable addins = new Hashtable ();
+
+ public void Add (AddinDescription desc)
+ {
+ string id = Addin.GetFullId (desc.Namespace, desc.LocalId, null);
+ ArrayList list = (ArrayList) addins [id];
+ if (list == null) {
+ list = new ArrayList ();
+ addins [id] = list;
+ }
+ list.Add (desc);
+ }
+
+ ArrayList FindDescriptions (string domain, string fullid)
+ {
+ // Returns all registered add-ins which are compatible with the provided
+ // fullid. Compatible means that the id is the same and the version is within
+ // the range of compatible versions of the add-in.
+
+ ArrayList res = new ArrayList ();
+ string id = Addin.GetIdName (fullid);
+ ArrayList list = (ArrayList) addins [id];
+ if (list == null)
+ return res;
+ string version = Addin.GetIdVersion (fullid);
+ foreach (AddinDescription desc in list) {
+ if ((desc.Domain == domain || domain == AddinDatabase.GlobalDomain) && desc.SupportsVersion (version))
+ res.Add (desc);
+ }
+ return res;
+ }
+
+ public ArrayList GetSortedAddins ()
+ {
+ Hashtable inserted = new Hashtable ();
+ Hashtable lists = new Hashtable ();
+
+ foreach (ArrayList dlist in addins.Values) {
+ foreach (AddinDescription desc in dlist)
+ InsertSortedAddin (inserted, lists, desc);
+ }
+
+ // Merge all domain lists into a single list.
+ // Make sure the global domain is inserted the last
+
+ ArrayList global = (ArrayList) lists [AddinDatabase.GlobalDomain];
+ lists.Remove (AddinDatabase.GlobalDomain);
+
+ ArrayList list = new ArrayList ();
+ foreach (ArrayList dl in lists.Values) {
+ list.AddRange (dl);
+ }
+ if (global != null)
+ list.AddRange (global);
+ return list;
+ }
+
+ void InsertSortedAddin (Hashtable inserted, Hashtable lists, AddinDescription desc)
+ {
+ string sid = desc.AddinId + " " + desc.Domain;
+ if (inserted.ContainsKey (sid))
+ return;
+ inserted [sid] = desc;
+ foreach (ModuleDescription mod in desc.AllModules) {
+ foreach (Dependency dep in mod.Dependencies) {
+ AddinDependency adep = dep as AddinDependency;
+ if (adep == null)
+ continue;
+ ArrayList descs = FindDescriptions (desc.Domain, adep.FullAddinId);
+ if (descs.Count > 0) {
+ foreach (AddinDescription sd in descs)
+ InsertSortedAddin (inserted, lists, sd);
+ } else
+ Console.WriteLine ("NOT FOUND: " + adep.FullAddinId + " " + desc.Domain);
+ }
+ }
+ ArrayList list = (ArrayList) lists [desc.Domain];
+ if (list == null) {
+ list = new ArrayList ();
+ lists [desc.Domain] = list;
+ }
+
+ list.Add (desc);
+ }
+ }
+
+ enum AddinType
+ {
+ Addin,
+ Root,
+ All
+ }
}
diff --git a/Mono.Addins/Mono.Addins.Database/AddinHostIndex.cs b/Mono.Addins/Mono.Addins.Database/AddinHostIndex.cs
index 1fea8de..d7b5174 100644
--- a/Mono.Addins/Mono.Addins.Database/AddinHostIndex.cs
+++ b/Mono.Addins/Mono.Addins.Database/AddinHostIndex.cs
@@ -39,35 +39,38 @@ namespace Mono.Addins.Database
Hashtable index = new Hashtable ();
- public void RegisterAssembly (string assemblyLocation, string addinId, string addinLocation)
+ public void RegisterAssembly (string assemblyLocation, string addinId, string addinLocation, string domain)
{
assemblyLocation = NormalizeFileName (assemblyLocation);
- index [Util.GetFullPath (assemblyLocation)] = addinId + " " + addinLocation;
+ index [Util.GetFullPath (assemblyLocation)] = addinId + " " + addinLocation + " " + domain;
}
- public bool GetAddinForAssembly (string assemblyLocation, out string addinId, out string addinLocation)
+ public bool GetAddinForAssembly (string assemblyLocation, out string addinId, out string addinLocation, out string domain)
{
assemblyLocation = NormalizeFileName (assemblyLocation);
string s = index [Util.GetFullPath (assemblyLocation)] as string;
if (s == null) {
addinId = null;
addinLocation = null;
+ domain = null;
return false;
}
else {
int i = s.IndexOf (' ');
+ int j = s.LastIndexOf (' ');
addinId = s.Substring (0, i);
- addinLocation = s.Substring (i+1);
+ addinLocation = s.Substring (i+1, j-i-1);
+ domain = s.Substring (j+1);
return true;
}
}
public void RemoveHostData (string addinId, string addinLocation)
{
- string loc = addinId + " " + Util.GetFullPath (addinLocation);
+ string loc = addinId + " " + Util.GetFullPath (addinLocation) + " ";
ArrayList todelete = new ArrayList ();
foreach (DictionaryEntry e in index) {
- if (((string)e.Value) == loc)
+ if (((string)e.Value).StartsWith (loc))
todelete.Add (e.Key);
}
foreach (string s in todelete)
diff --git a/Mono.Addins/Mono.Addins.Database/AddinScanFolderInfo.cs b/Mono.Addins/Mono.Addins.Database/AddinScanFolderInfo.cs
index e6f4af5..cac7d66 100644
--- a/Mono.Addins/Mono.Addins.Database/AddinScanFolderInfo.cs
+++ b/Mono.Addins/Mono.Addins.Database/AddinScanFolderInfo.cs
@@ -39,6 +39,8 @@ namespace Mono.Addins.Database
Hashtable files = new Hashtable ();
string folder;
string fileName;
+ string domain;
+ bool sharedFolder = true;
static BinaryXmlTypeMap typeMap = new BinaryXmlTypeMap (
typeof(AddinScanFolderInfo),
@@ -69,13 +71,13 @@ namespace Mono.Addins.Database
public static AddinScanFolderInfo Read (FileDatabase filedb, string basePath, string folderPath)
{
string fileName;
- AddinScanFolderInfo finfo = (AddinScanFolderInfo) filedb.ReadSharedObject (basePath, GetFolderId (folderPath), ".data", Util.GetFullPath (folderPath), typeMap, out fileName);
+ AddinScanFolderInfo finfo = (AddinScanFolderInfo) filedb.ReadSharedObject (basePath, GetDomain (folderPath), ".data", Util.GetFullPath (folderPath), typeMap, out fileName);
if (finfo != null)
finfo.fileName = fileName;
return finfo;
}
- static string GetFolderId (string path)
+ static string GetDomain (string path)
{
path = Util.GetFullPath (path);
string s = path.Replace (Path.DirectorySeparatorChar, '_');
@@ -89,12 +91,60 @@ namespace Mono.Addins.Database
public void Write (FileDatabase filedb, string basePath)
{
- filedb.WriteSharedObject (basePath, GetFolderId (folder), ".data", Util.GetFullPath (folder), fileName, typeMap, this);
+ filedb.WriteSharedObject (basePath, GetDomain (folder), ".data", Util.GetFullPath (folder), fileName, typeMap, this);
+ }
+
+ public string GetExistingLocalDomain ()
+ {
+ foreach (AddinFileInfo info in files.Values) {
+ if (info.Domain != null && info.Domain != AddinDatabase.GlobalDomain)
+ return info.Domain;
+ }
+ return AddinDatabase.GlobalDomain;
}
public string Folder {
get { return folder; }
}
+
+ public string Domain {
+ get {
+ if (sharedFolder)
+ return AddinDatabase.GlobalDomain;
+ else
+ return domain;
+ }
+ set {
+ domain = value;
+ sharedFolder = true;
+ }
+ }
+
+ public string RootsDomain {
+ get {
+ return domain;
+ }
+ set {
+ domain = value;
+ }
+ }
+
+ public string GetDomain (bool isRoot)
+ {
+ if (isRoot)
+ return RootsDomain;
+ else
+ return Domain;
+ }
+
+ public bool SharedFolder {
+ get {
+ return sharedFolder;
+ }
+ set {
+ sharedFolder = value;
+ }
+ }
public DateTime GetLastScanTime (string file)
{
@@ -122,6 +172,10 @@ namespace Mono.Addins.Database
info.AddinId = addinId;
info.IsRoot = isRoot;
info.ScanError = scanError;
+ if (addinId != null)
+ info.Domain = GetDomain (isRoot);
+ else
+ info.Domain = null;
}
public ArrayList GetMissingAddins ()
@@ -131,7 +185,7 @@ namespace Mono.Addins.Database
if (!Directory.Exists (folder)) {
// All deleted
foreach (AddinFileInfo info in files.Values) {
- if (info.AddinId != null && info.AddinId.Length > 0)
+ if (info.IsAddin)
missing.Add (info);
}
files.Clear ();
@@ -140,10 +194,13 @@ namespace Mono.Addins.Database
ArrayList toDelete = new ArrayList ();
foreach (AddinFileInfo info in files.Values) {
if (!File.Exists (info.File)) {
- if (info.AddinId != null && info.AddinId.Length > 0)
+ if (info.IsAddin)
missing.Add (info);
toDelete.Add (info.File);
}
+ else if (info.IsAddin && info.Domain != GetDomain (info.IsRoot)) {
+ missing.Add (info);
+ }
}
foreach (string file in toDelete)
files.Remove (file);
@@ -153,14 +210,22 @@ namespace Mono.Addins.Database
void IBinaryXmlElement.Write (BinaryXmlWriter writer)
{
+ if (files.Count == 0) {
+ domain = null;
+ sharedFolder = true;
+ }
writer.WriteValue ("folder", folder);
writer.WriteValue ("files", files);
+ writer.WriteValue ("domain", domain);
+ writer.WriteValue ("sharedFolder", sharedFolder);
}
void IBinaryXmlElement.Read (BinaryXmlReader reader)
{
folder = reader.ReadStringValue ("folder");
reader.ReadValue ("files", files);
+ domain = reader.ReadStringValue ("domain");
+ sharedFolder = reader.ReadBooleanValue ("sharedFolder");
}
}
@@ -172,6 +237,11 @@ namespace Mono.Addins.Database
public string AddinId;
public bool IsRoot;
public bool ScanError;
+ public string Domain;
+
+ public bool IsAddin {
+ get { return AddinId != null && AddinId.Length != 0; }
+ }
void IBinaryXmlElement.Write (BinaryXmlWriter writer)
{
@@ -180,6 +250,7 @@ namespace Mono.Addins.Database
writer.WriteValue ("AddinId", AddinId);
writer.WriteValue ("IsRoot", IsRoot);
writer.WriteValue ("ScanError", ScanError);
+ writer.WriteValue ("Domain", Domain);
}
void IBinaryXmlElement.Read (BinaryXmlReader reader)
@@ -189,6 +260,7 @@ namespace Mono.Addins.Database
AddinId = reader.ReadStringValue ("AddinId");
IsRoot = reader.ReadBooleanValue ("IsRoot");
ScanError = reader.ReadBooleanValue ("ScanError");
+ Domain = reader.ReadStringValue ("Domain");
}
}
}
diff --git a/Mono.Addins/Mono.Addins.Database/AddinScanner.cs b/Mono.Addins/Mono.Addins.Database/AddinScanner.cs
index 9614155..42fe59d 100644
--- a/Mono.Addins/Mono.Addins.Database/AddinScanner.cs
+++ b/Mono.Addins/Mono.Addins.Database/AddinScanner.cs
@@ -49,7 +49,7 @@ namespace Mono.Addins.Database
this.database = database;
}
- public void ScanFolder (IProgressStatus monitor, string path, AddinScanResult scanResult)
+ public void ScanFolder (IProgressStatus monitor, string path, string domain, AddinScanResult scanResult)
{
path = Util.GetFullPath (path);
@@ -71,9 +71,32 @@ namespace Mono.Addins.Database
return;
}
+ // if domain is null it means that a new domain has to be created.
+
+ bool sharedFolder = domain == AddinDatabase.GlobalDomain;
+
if (folderInfo == null)
folderInfo = new AddinScanFolderInfo (path);
+ if (!sharedFolder && (folderInfo.SharedFolder || folderInfo.Domain != domain)) {
+ // If the folder already has a domain, reuse it
+ if (domain == null && folderInfo.RootsDomain != null && folderInfo.RootsDomain != AddinDatabase.GlobalDomain)
+ domain = folderInfo.RootsDomain;
+ else if (domain == null) {
+ folderInfo.Domain = domain = database.GetUniqueDomainId ();
+ scanResult.RegenerateRelationData = true;
+ }
+ else {
+ folderInfo.Domain = domain;
+ scanResult.RegenerateRelationData = true;
+ }
+ }
+ else if (!folderInfo.SharedFolder && sharedFolder) {
+ scanResult.RegenerateRelationData = true;
+ }
+
+ folderInfo.SharedFolder = sharedFolder;
+
if (Directory.Exists (path))
{
string[] files = Directory.GetFiles (path);
@@ -95,7 +118,7 @@ namespace Mono.Addins.Database
scanResult.AddAssemblyLocation (file);
break;
case ".addins":
- ScanAddinsFile (monitor, file, scanResult);
+ ScanAddinsFile (monitor, file, domain, scanResult);
break;
}
}
@@ -128,10 +151,7 @@ namespace Mono.Addins.Database
return;
foreach (AddinFileInfo info in missing) {
- if (info.IsRoot)
- database.UninstallRootAddin (monitor, info.AddinId, info.File, scanResult);
- else
- database.UninstallAddin (monitor, info.AddinId, scanResult);
+ database.UninstallAddin (monitor, info.Domain, info.AddinId, scanResult);
}
}
}
@@ -144,7 +164,7 @@ namespace Mono.Addins.Database
AddinFileInfo finfo = folderInfo.GetAddinFileInfo (file);
bool added = false;
- if (finfo != null && File.GetLastWriteTime (file) == finfo.LastScan && !scanResult.RegenerateAllData) {
+ if (finfo != null && (!finfo.IsAddin || finfo.Domain == folderInfo.GetDomain (finfo.IsRoot)) && File.GetLastWriteTime (file) == finfo.LastScan && !scanResult.RegenerateAllData) {
if (finfo.ScanError) {
// Always schedule the file for scan if there was an error in a previous scan.
// However, don't set ChangesFound=true, in this way if there isn't any other
@@ -153,15 +173,10 @@ namespace Mono.Addins.Database
added = true;
}
- if (finfo.AddinId == null || finfo.AddinId.Length == 0)
+ if (!finfo.IsAddin)
+ return;
+ if (database.AddinDescriptionExists (finfo.Domain, finfo.AddinId))
return;
- if (!finfo.IsRoot) {
- if (database.AddinDescriptionExists (finfo.AddinId))
- return;
- } else {
- if (database.HostDescriptionExists (finfo.AddinId, file))
- return;
- }
}
scanResult.ChangesFound = true;
@@ -239,12 +254,7 @@ namespace Mono.Addins.Database
// Also, the dependencies of the old add-in need to be re-analized
AddinDescription existingDescription = null;
- bool res;
-
- if (config.IsRoot)
- res = database.GetHostDescription (monitor, config.AddinId, config.AddinFile, out existingDescription);
- else
- res = database.GetAddinDescription (monitor, config.AddinId, out existingDescription);
+ bool res = database.GetAddinDescription (monitor, folderInfo.Domain, config.AddinId, out existingDescription);
// If we can't get information about the old assembly, just regenerate all relation data
if (!res)
@@ -261,11 +271,8 @@ namespace Mono.Addins.Database
// If the scanned file results in an add-in version different from the one obtained from
// previous scans, the old add-in needs to be uninstalled.
- if (fi != null && fi.AddinId != null && fi.AddinId != config.AddinId) {
- if (fi.IsRoot)
- database.UninstallRootAddin (monitor, fi.AddinId, file, scanResult);
- else
- database.UninstallAddin (monitor, fi.AddinId, scanResult);
+ if (fi != null && fi.IsAddin && fi.AddinId != config.AddinId) {
+ database.UninstallAddin (monitor, folderInfo.Domain, fi.AddinId, scanResult);
// If the add-in version has changed, regenerate everything again since old data can't be reused
if (Addin.GetIdName (fi.AddinId) == Addin.GetIdName (config.AddinId))
@@ -274,6 +281,23 @@ namespace Mono.Addins.Database
// If a description could be generated, save it now (if the scan was successful)
if (scanSuccessful) {
+
+ // Assign the domain
+ if (config.IsRoot) {
+ if (folderInfo.RootsDomain == null)
+ folderInfo.RootsDomain = database.GetUniqueDomainId ();
+ config.Domain = folderInfo.RootsDomain;
+ } else
+ config.Domain = folderInfo.Domain;
+
+ if (config.IsRoot && scanResult.HostIndex != null) {
+ // If the add-in is a root, register its assemblies
+ foreach (string f in config.MainModule.Assemblies) {
+ string asmFile = Path.Combine (config.BasePath, f);
+ scanResult.HostIndex.RegisterAssembly (asmFile, config.AddinId, config.AddinFile, config.Domain);
+ }
+ }
+
if (database.SaveDescription (monitor, config, replaceFileName)) {
// The new dependencies also have to be updated
Util.AddDependencies (config, scanResult);
@@ -331,11 +355,11 @@ namespace Mono.Addins.Database
return config;
}
- public void ScanAddinsFile (IProgressStatus monitor, string file, AddinScanResult scanResult)
+ public void ScanAddinsFile (IProgressStatus monitor, string file, string domain, AddinScanResult scanResult)
{
XmlTextReader r = null;
- StringCollection directories = new StringCollection ();
- StringCollection directoriesWithSubdirs = new StringCollection ();
+ ArrayList directories = new ArrayList ();
+ ArrayList directoriesWithSubdirs = new ArrayList ();
try {
r = new XmlTextReader (new StreamReader (file));
r.MoveToContent ();
@@ -346,20 +370,31 @@ namespace Mono.Addins.Database
while (r.NodeType != XmlNodeType.EndElement) {
if (r.NodeType == XmlNodeType.Element && r.LocalName == "Directory") {
string subs = r.GetAttribute ("include-subdirs");
+ string sdom;
+ string share = r.GetAttribute ("shared");
+ if (share == "true")
+ sdom = AddinDatabase.GlobalDomain;
+ else if (share == "false")
+ sdom = null;
+ else
+ sdom = domain; // Inherit the domain
+
string path = r.ReadElementString ().Trim ();
if (path.Length > 0) {
if (subs == "true")
- directoriesWithSubdirs.Add (path);
+ directoriesWithSubdirs.Add (new string[] {path, sdom});
else
- directories.Add (path);
+ directories.Add (new string[] {path, sdom});
}
}
else if (r.NodeType == XmlNodeType.Element && r.LocalName == "GacAssembly") {
string aname = r.ReadElementString ().Trim ();
if (aname.Length > 0) {
aname = Util.GetGacPath (aname);
- if (aname != null)
- directories.Add (aname);
+ if (aname != null) {
+ // Gac assemblies always use the global domain
+ directories.Add (new string[] {aname, AddinDatabase.GlobalDomain});
+ }
}
}
else
@@ -373,29 +408,29 @@ namespace Mono.Addins.Database
if (r != null)
r.Close ();
}
- foreach (string d in directories) {
- string dir = d;
+ foreach (string[] d in directories) {
+ string dir = d[0];
if (!Path.IsPathRooted (dir))
dir = Path.Combine (Path.GetDirectoryName (file), dir);
- ScanFolder (monitor, dir, scanResult);
+ ScanFolder (monitor, dir, d[1], scanResult);
}
- foreach (string d in directoriesWithSubdirs) {
- string dir = d;
+ foreach (string[] d in directoriesWithSubdirs) {
+ string dir = d[0];
if (!Path.IsPathRooted (dir))
dir = Path.Combine (Path.GetDirectoryName (file), dir);
- ScanFolderRec (monitor, dir, scanResult);
+ ScanFolderRec (monitor, dir, d[1], scanResult);
}
}
- public void ScanFolderRec (IProgressStatus monitor, string dir, AddinScanResult scanResult)
+ public void ScanFolderRec (IProgressStatus monitor, string dir, string domain, AddinScanResult scanResult)
{
- ScanFolder (monitor, dir, scanResult);
+ ScanFolder (monitor, dir, domain, scanResult);
if (!Directory.Exists (dir))
return;
foreach (string sd in Directory.GetDirectories (dir))
- ScanFolderRec (monitor, sd, scanResult);
+ ScanFolderRec (monitor, sd, domain, scanResult);
}
bool ScanConfigAssemblies (IProgressStatus monitor, string filePath, AddinScanResult scanResult, out AddinDescription config)
@@ -503,12 +538,6 @@ namespace Mono.Addins.Database
foreach (Assembly asm in assemblies)
ScanAssemblyContents (config, asm, hostExtensionClasses, scanResult);
- if (config.IsRoot && scanResult.HostIndex != null) {
- // If the add-in is a root, register its assemblies
- foreach (string asmFile in asmFiles)
- scanResult.HostIndex.RegisterAssembly (asmFile, config.AddinId, config.AddinFile);
- }
-
} catch (Exception ex) {
ReportReflectionException (monitor, ex, config, scanResult);
return false;
@@ -545,12 +574,6 @@ namespace Mono.Addins.Database
}
foreach (Assembly asm in assemblies)
ScanAssemblyContents (config, asm, null, scanResult);
-
- if (config.IsRoot && scanResult.HostIndex != null) {
- // If the add-in is a root, register its assemblies
- foreach (string asmFile in asmFiles)
- scanResult.HostIndex.RegisterAssembly (asmFile, config.AddinId, config.AddinFile);
- }
} catch (Exception ex) {
ReportReflectionException (monitor, ex, config, scanResult);
@@ -572,7 +595,6 @@ namespace Mono.Addins.Database
ReflectionTypeLoadException rex = ex as ReflectionTypeLoadException;
if (rex != null) {
- Console.WriteLine ("pp e: " + ex.InnerException);
foreach (Exception e in rex.LoaderExceptions)
monitor.Log ("Load exception: " + e);
}
diff --git a/Mono.Addins/Mono.Addins.Database/AddinUpdateData.cs b/Mono.Addins/Mono.Addins.Database/AddinUpdateData.cs
index ebcfc99..e0b0eb2 100644
--- a/Mono.Addins/Mono.Addins.Database/AddinUpdateData.cs
+++ b/Mono.Addins/Mono.Addins.Database/AddinUpdateData.cs
@@ -57,213 +57,129 @@ namespace Mono.Addins.Database
public ExtensionPoint ExtensionPoint;
}
- AddinDatabase database;
+ IProgressStatus monitor;
- public AddinUpdateData (AddinDatabase database)
+ public AddinUpdateData (AddinDatabase database, IProgressStatus monitor)
{
- this.database = database;
+ this.monitor = monitor;
}
- public void RegisterAddinRootExtensionPoint (AddinDescription description, ExtensionPoint ep)
+ public void RegisterNodeSet (AddinDescription description, ExtensionNodeSet nset)
{
- RelExtensionPoints++;
- ArrayList list = (ArrayList) pathHash [ep.Path];
- if (list == null) {
- list = new ArrayList ();
- pathHash [ep.Path] = list;
+ ArrayList extensions = (ArrayList) nodeSetHash [nset.Id];
+ if (extensions != null) {
+ // Extension point already registered
+ ArrayList compatExtensions = GetCompatibleExtensionPoints (nset.Id, description, description.MainModule, extensions);
+ if (compatExtensions.Count > 0) {
+ foreach (ExtensionPoint einfo in compatExtensions)
+ einfo.NodeSet.MergeWith (null, nset);
+ return;
+ }
}
-
+ // Create a new extension set
RootExtensionPoint rep = new RootExtensionPoint ();
+ rep.ExtensionPoint = new ExtensionPoint ();
+ rep.ExtensionPoint.SetNodeSet (nset);
+ rep.ExtensionPoint.RootAddin = description.AddinId;
+ rep.ExtensionPoint.Path = nset.Id;
rep.Description = description;
- rep.ExtensionPoint = ep;
- ep.RootAddin = description.AddinId;
- list.Add (rep);
+ if (extensions == null) {
+ extensions = new ArrayList ();
+ nodeSetHash [nset.Id] = extensions;
+ }
+ extensions.Add (rep);
}
-
- public void RegisterAddinRootNodeSet (AddinDescription description, ExtensionNodeSet nodeSet)
+
+ public void RegisterExtensionPoint (AddinDescription description, ExtensionPoint ep)
{
- ArrayList list = (ArrayList) nodeSetHash [nodeSet.Id];
- if (list == null) {
- list = new ArrayList ();
- nodeSetHash [nodeSet.Id] = list;
+ ArrayList extensions = (ArrayList) pathHash [ep.Path];
+ if (extensions != null) {
+ // Extension point already registered
+ ArrayList compatExtensions = GetCompatibleExtensionPoints (ep.Path, description, description.MainModule, extensions);
+ if (compatExtensions.Count > 0) {
+ foreach (ExtensionPoint einfo in compatExtensions)
+ einfo.MergeWith (null, ep);
+ RegisterObjectTypes (ep);
+ return;
+ }
}
-
+ // Create a new extension
RootExtensionPoint rep = new RootExtensionPoint ();
- rep.Description = description;
- ExtensionPoint ep = new ExtensionPoint ();
- ep.RootAddin = description.AddinId;
- ep.SetNodeSet (nodeSet);
rep.ExtensionPoint = ep;
- list.Add (rep);
- }
-
- public void RegisterNodeSet (AddinDescription description, ExtensionNodeSet nset)
- {
- string id = Addin.GetFullId (description.Namespace, nset.Id, description.Version);
- foreach (ExtensionPoint einfo in GetExtensionInfo (nodeSetHash, id, description, description.MainModule, false)) {
- if (einfo.RootAddin == null || database.AddinDependsOn (einfo.RootAddin, description.AddinId))
- einfo.RootAddin = description.AddinId;
- einfo.NodeSet.MergeWith (null, nset);
+ rep.ExtensionPoint.RootAddin = description.AddinId;
+ rep.Description = description;
+ if (extensions == null) {
+ extensions = new ArrayList ();
+ pathHash [ep.Path] = extensions;
}
+ extensions.Add (rep);
+ RegisterObjectTypes (ep);
}
-
- public void RegisterExtensionPoint (AddinDescription description, ExtensionPoint ep)
+
+ void RegisterObjectTypes (ExtensionPoint ep)
{
- foreach (ExtensionPoint einfo in GetExtensionInfo (pathHash, ep.Path, description, description.MainModule, false)) {
- if (einfo.RootAddin == null || database.AddinDependsOn (einfo.RootAddin, description.AddinId))
- einfo.RootAddin = description.AddinId;
- einfo.MergeWith (null, ep);
+ // Register extension points bound to a node type
+
+ foreach (ExtensionNodeType nt in ep.NodeSet.NodeTypes) {
+ if (nt.ObjectTypeName.Length > 0) {
+ ArrayList list = (ArrayList) objectTypeExtensions [nt.ObjectTypeName];
+ if (list == null) {
+ list = new ArrayList ();
+ objectTypeExtensions [nt.ObjectTypeName] = list;
+ }
+ list.Add (ep);
+ }
}
}
public void RegisterExtension (AddinDescription description, ModuleDescription module, Extension extension)
{
if (extension.Path.StartsWith ("$")) {
- UnresolvedObjectTypeExtension extData = new UnresolvedObjectTypeExtension ();
- extData.Description = description;
- extData.ModuleDescription = module;
- extData.Extension = extension;
string[] objectTypes = extension.Path.Substring (1).Split (',');
+ bool found = false;
foreach (string s in objectTypes) {
ArrayList list = (ArrayList) objectTypeExtensions [s];
- if (list == null) {
- list = new ArrayList ();
- objectTypeExtensions [s] = list;
- }
- list.Add (extData);
- }
- }
- }
-
- void CollectObjectTypeExtensions (AddinDescription desc, ExtensionPoint ep, string objectTypeName)
- {
- ArrayList list = (ArrayList) objectTypeExtensions [objectTypeName];
- if (list == null)
- return;
-
- foreach (UnresolvedObjectTypeExtension data in list) {
- if (IsAddinCompatible (desc, data.Description, data.ModuleDescription)) {
- data.Extension.Path = ep.Path;
- RegisterExtension (data.Description, data.ModuleDescription, ep.Path);
- data.FoundExtensionPoint = true;
- }
- }
- }
-
- public void RegisterExtension (AddinDescription description, ModuleDescription module, string path)
- {
- foreach (ExtensionPoint einfo in GetExtensionInfo (pathHash, path, description, module, true)) {
- if (!einfo.Addins.Contains (description.AddinId))
- einfo.Addins.Add (description.AddinId);
- }
- }
-
- public IEnumerable GetUnresolvedExtensionPoints ()
- {
- ArrayList list = new ArrayList ();
- foreach (object ob in pathHash.Values)
- if (ob is ExtensionPoint)
- list.Add (ob);
- return list;
- }
-
- public IEnumerable GetUnresolvedExtensionSets ()
- {
- ArrayList list = new ArrayList ();
- foreach (object ob in nodeSetHash.Values)
- if (ob is ExtensionPoint)
- list.Add (ob);
- return list;
- }
-
- public void ResolveExtensions (IProgressStatus monitor, Hashtable descriptions)
- {
- // Make a copy of the extensions found, sice the hash may change while being scanned
- object[] extensionPointsFound = new object [pathHash.Count];
- pathHash.Values.CopyTo (extensionPointsFound, 0);
-
- foreach (object ob in extensionPointsFound) {
- ExtensionPoint ep = ob as ExtensionPoint;
-
- if (ep == null) {
- // It is a list of extension from a root add-in
- ArrayList rootExtensionPoints = (ArrayList) ob;
- foreach (RootExtensionPoint rep in rootExtensionPoints) {
- foreach (ExtensionNodeType nt in rep.ExtensionPoint.NodeSet.NodeTypes) {
- if (nt.ObjectTypeName.Length > 0)
- CollectObjectTypeExtensions (rep.Description, rep.ExtensionPoint, nt.ObjectTypeName);
- }
- }
- continue;
- }
-
- if (ep.RootAddin == null) {
- // Ignore class extensions
- if (!ep.Path.StartsWith ("$")) {
- // No add-in has defined this extension point, but some add-in
- // is trying to extend it. A parent extension may exist. Check it now.
- ExtensionPoint pep = GetParentExtensionPoint (ep.Path);
- if (pep != null) {
- foreach (string a in ep.Addins)
- if (!pep.Addins.Contains (a))
- pep.Addins.Add (a);
- } else {
- foreach (string s in ep.Addins)
- monitor.ReportWarning ("The add-in '" + s + "' is trying to extend '" + ep.Path + "', but there isn't any add-in defining this extension point");
+ if (list != null) {
+ found = true;
+ foreach (ExtensionPoint ep in list) {
+ if (IsAddinCompatible (ep.ParentAddinDescription, description, module)) {
+ extension.Path = ep.Path;
+ RegisterExtension (description, module, ep.Path);
+ }
}
}
- pathHash.Remove (ep.Path);
- }
- else {
- foreach (ExtensionNodeType nt in ep.NodeSet.NodeTypes) {
- if (nt.ObjectTypeName.Length > 0) {
- AddinDescription desc = (AddinDescription) descriptions [ep.RootAddin];
- CollectObjectTypeExtensions (desc, ep, nt.ObjectTypeName);
- }
- }
- }
- }
-
- foreach (ArrayList list in objectTypeExtensions.Values) {
- foreach (UnresolvedObjectTypeExtension data in list) {
- if (!data.FoundExtensionPoint) {
- monitor.ReportWarning ("The add-in '" + data.Description.AddinId + "' is trying to register the class '" + data.Extension.Path + "', but there isn't any add-in defining a suitable extension point");
- // The type extensions may be registered using different base classes.
- // Make sure the warning is shown only once
- data.FoundExtensionPoint = true;
- }
}
+ if (!found)
+ monitor.ReportWarning ("The add-in '" + description.AddinId + "' is trying to register the class '" + extension.Path.Substring (1) + "', but there isn't any add-in defining a suitable extension point");
}
}
- IEnumerable GetExtensionInfo (Hashtable hash, string path, AddinDescription description, ModuleDescription module, bool lookInParents)
+ public void RegisterExtension (AddinDescription description, ModuleDescription module, string path)
{
- ArrayList list = new ArrayList ();
-
- object data = hash [path];
- if (data == null && lookInParents) {
+ ArrayList extensions = (ArrayList) pathHash [path];
+ if (extensions == null) {
// Root add-in extension points are registered before any other kind of extension,
// so we should find it now.
- data = GetParentExtensionInfo (path);
+ extensions = GetParentExtensionInfo (path);
}
-
- if (data is ArrayList) {
- // Extension point which belongs to a root assembly.
- list.AddRange (GetRootExtensionInfo (hash, path, description, module, (ArrayList) data));
+ if (extensions == null) {
+ monitor.ReportWarning ("The add-in '" + description.AddinId + "' is trying to extend '" + path + "', but there isn't any add-in defining this extension point");
+ return;
}
- else {
- ExtensionPoint info = (ExtensionPoint) data;
- if (info == null) {
- info = new ExtensionPoint ();
- info.Path = path;
- hash [path] = info;
+
+ bool found = false;
+ foreach (RootExtensionPoint einfo in extensions) {
+ if (IsAddinCompatible (einfo.Description, description, module)) {
+ if (!einfo.ExtensionPoint.Addins.Contains (description.AddinId))
+ einfo.ExtensionPoint.Addins.Add (description.AddinId);
+ found = true;
}
- list.Add (info);
}
- return list;
+ if (!found)
+ monitor.ReportWarning ("The add-in '" + description.AddinId + "' is trying to extend '" + path + "', but there isn't any compatible add-in defining this extension point");
}
-
- ArrayList GetRootExtensionInfo (Hashtable hash, string path, AddinDescription description, ModuleDescription module, ArrayList rootExtensionPoints)
+
+ ArrayList GetCompatibleExtensionPoints (string path, AddinDescription description, ModuleDescription module, ArrayList rootExtensionPoints)
{
ArrayList list = new ArrayList ();
foreach (RootExtensionPoint rep in rootExtensionPoints) {
@@ -275,18 +191,13 @@ namespace Mono.Addins.Database
return list;
}
- ExtensionPoint GetParentExtensionPoint (string path)
- {
- return GetParentExtensionInfo (path) as ExtensionPoint;
- }
-
- object GetParentExtensionInfo (string path)
+ ArrayList GetParentExtensionInfo (string path)
{
int i = path.LastIndexOf ('/');
if (i == -1)
return null;
string np = path.Substring (0, i);
- object ep = pathHash [np];
+ ArrayList ep = (ArrayList) pathHash [np];
if (ep != null)
return ep;
else
@@ -295,6 +206,14 @@ namespace Mono.Addins.Database
bool IsAddinCompatible (AddinDescription installedDescription, AddinDescription description, ModuleDescription module)
{
+ if (installedDescription == description)
+ return true;
+ if (installedDescription.Domain != AddinDatabase.GlobalDomain) {
+ if (description.Domain != AddinDatabase.GlobalDomain && description.Domain != installedDescription.Domain)
+ return false;
+ } else if (description.Domain != AddinDatabase.GlobalDomain)
+ return false;
+
string addinId = Addin.GetFullId (installedDescription.Namespace, installedDescription.LocalId, null);
string requiredVersion = null;
@@ -317,12 +236,4 @@ namespace Mono.Addins.Database
return true;
}
}
-
- class UnresolvedObjectTypeExtension
- {
- public AddinDescription Description;
- public ModuleDescription ModuleDescription;
- public Extension Extension;
- public bool FoundExtensionPoint;
- }
}
diff --git a/Mono.Addins/Mono.Addins.Database/FileDatabase.cs b/Mono.Addins/Mono.Addins.Database/FileDatabase.cs
index 798ffd3..1f78f2b 100644
--- a/Mono.Addins/Mono.Addins.Database/FileDatabase.cs
+++ b/Mono.Addins/Mono.Addins.Database/FileDatabase.cs
@@ -205,6 +205,30 @@ namespace Mono.Addins.Database
return File.Exists (fileName);
}
+ public bool DirExists (string dir)
+ {
+ return Directory.Exists (dir);
+ }
+
+ public void CreateDir (string dir)
+ {
+ Directory.CreateDirectory (dir);
+ }
+
+ public string[] GetDirectories (string dir)
+ {
+ return Directory.GetDirectories (dir);
+ }
+
+ public bool DirectoryIsEmpty (string dir)
+ {
+ foreach (string f in Directory.GetFiles (dir)) {
+ if (!inTransaction || !deletedFiles.Contains (f))
+ return false;
+ }
+ return true;
+ }
+
public string[] GetDirectoryFiles (string dir, string pattern)
{
if (pattern == null || pattern.Length == 0 || pattern.EndsWith ("*"))
diff --git a/Mono.Addins/Mono.Addins.Description/AddinDescription.cs b/Mono.Addins/Mono.Addins.Description/AddinDescription.cs
index bab72d0..984cc55 100644
--- a/Mono.Addins/Mono.Addins.Description/AddinDescription.cs
+++ b/Mono.Addins/Mono.Addins.Description/AddinDescription.cs
@@ -43,7 +43,6 @@ namespace Mono.Addins.Description
{
XmlDocument configDoc;
string configFile;
- bool fromBinaryFile;
AddinDatabase ownerDatabase;
string id;
@@ -62,6 +61,7 @@ namespace Mono.Addins.Description
bool hasUserId;
bool canWrite = true;
bool defaultEnabled = true;
+ string domain;
ModuleDescription mainModule;
ModuleCollection optionalModules;
@@ -183,6 +183,12 @@ namespace Mono.Addins.Description
set { hasUserId = value; }
}
+ internal bool SupportsVersion (string ver)
+ {
+ return Addin.CompareVersions (ver, Version) >= 0 &&
+ (CompatVersion.Length == 0 || Addin.CompareVersions (ver, CompatVersion) <= 0);
+ }
+
public StringCollection AllFiles {
get {
StringCollection col = new StringCollection ();
@@ -309,7 +315,7 @@ namespace Mono.Addins.Description
foreach (Dependency dep in MainModule.Dependencies) {
AddinDependency adep = dep as AddinDependency;
if (adep == null) continue;
- Addin ad = OwnerDatabase.GetInstalledAddin (adep.FullAddinId);
+ Addin ad = OwnerDatabase.GetInstalledAddin (Domain, adep.FullAddinId);
if (ad != null && ad.Description != null) {
ExtensionNodeDescription node = ad.Description.FindExtensionNode (path, false);
if (node != null)
@@ -333,6 +339,11 @@ namespace Mono.Addins.Description
set { configFile = value; }
}
+ internal string Domain {
+ get { return domain; }
+ set { domain = value; }
+ }
+
internal void StoreFileInfo ()
{
ArrayList list = new ArrayList ();
@@ -525,19 +536,6 @@ namespace Mono.Addins.Description
AddinDescription description = (AddinDescription) fdb.ReadSharedObject (configFile, typeMap);
if (description != null) {
description.FileName = configFile;
- description.fromBinaryFile = true;
- description.canWrite = !fdb.IgnoreDescriptionData;
- }
- return description;
- }
-
- internal static AddinDescription ReadHostBinary (FileDatabase fdb, string basePath, string addinId, string addinFile)
- {
- string fileName;
- AddinDescription description = (AddinDescription) fdb.ReadSharedObject (basePath, addinId, ".mroot", Util.GetFullPath (addinFile), typeMap, out fileName);
- if (description != null) {
- description.FileName = fileName;
- description.fromBinaryFile = true;
description.canWrite = !fdb.IgnoreDescriptionData;
}
return description;
@@ -557,15 +555,6 @@ namespace Mono.Addins.Description
// BinaryXmlReader.DumpFile (configFile);
}
- internal void SaveHostBinary (FileDatabase fdb, string basePath)
- {
- if (!canWrite)
- throw new InvalidOperationException ("Can't write incomplete description.");
- if (!fromBinaryFile)
- FileName = null;
- FileName = fdb.WriteSharedObject (basePath, AddinId, ".mroot", AddinFile, FileName, typeMap, this);
- }
-
public StringCollection Verify ()
{
StringCollection errors = new StringCollection ();
@@ -573,8 +562,6 @@ namespace Mono.Addins.Description
if (IsRoot) {
if (OptionalModules.Count > 0)
errors.Add ("Root add-in hosts can't have optional modules.");
- if (MainModule.Dependencies.Count > 0)
- errors.Add ("Root add-in hosts can't have dependencies.");
}
if (AddinId.Length == 0 || Version.Length == 0) {
@@ -664,6 +651,7 @@ namespace Mono.Addins.Description
writer.WriteValue ("basePath", basePath);
writer.WriteValue ("sourceAddinFile", sourceAddinFile);
writer.WriteValue ("defaultEnabled", defaultEnabled);
+ writer.WriteValue ("domain", domain);
writer.WriteValue ("MainModule", MainModule);
writer.WriteValue ("OptionalModules", OptionalModules);
writer.WriteValue ("NodeSets", ExtensionNodeSets);
@@ -689,6 +677,7 @@ namespace Mono.Addins.Description
basePath = reader.ReadStringValue ("basePath");
sourceAddinFile = reader.ReadStringValue ("sourceAddinFile");
defaultEnabled = reader.ReadBooleanValue ("defaultEnabled");
+ domain = reader.ReadStringValue ("domain");
mainModule = (ModuleDescription) reader.ReadValue ("MainModule");
optionalModules = (ModuleCollection) reader.ReadValue ("OptionalModules", new ModuleCollection (this));
nodeSets = (ExtensionNodeSetCollection) reader.ReadValue ("NodeSets", new ExtensionNodeSetCollection (this));
diff --git a/Mono.Addins/Mono.Addins.Description/Extension.cs b/Mono.Addins/Mono.Addins.Description/Extension.cs
index eeeb1ac..b145a18 100644
--- a/Mono.Addins/Mono.Addins.Description/Extension.cs
+++ b/Mono.Addins/Mono.Addins.Description/Extension.cs
@@ -60,7 +60,7 @@ namespace Mono.Addins.Description
foreach (Dependency dep in desc.MainModule.Dependencies) {
AddinDependency adep = dep as AddinDependency;
if (adep == null) continue;
- Addin ad = desc.OwnerDatabase.GetInstalledAddin (adep.FullAddinId);
+ Addin ad = desc.OwnerDatabase.GetInstalledAddin (ParentAddinDescription.Domain, adep.FullAddinId);
if (ad != null && ad.Description != null) {
ep = FindExtensionPoint (ad.Description, path);
if (ep != null)
diff --git a/Mono.Addins/Mono.Addins.Description/ExtensionNodeSet.cs b/Mono.Addins/Mono.Addins.Description/ExtensionNodeSet.cs
index a6fc315..2d85188 100644
--- a/Mono.Addins/Mono.Addins.Description/ExtensionNodeSet.cs
+++ b/Mono.Addins/Mono.Addins.Description/ExtensionNodeSet.cs
@@ -161,7 +161,7 @@ namespace Mono.Addins.Description
string startAddin = ns [1];
if (startAddin == null || startAddin.Length == 0)
startAddin = desc.AddinId;
- ExtensionNodeSet nset = desc.OwnerDatabase.FindNodeSet (startAddin, ns[0]);
+ ExtensionNodeSet nset = desc.OwnerDatabase.FindNodeSet (ParentAddinDescription.Domain, startAddin, ns[0]);
if (nset != null)
nset.GetAllowedNodeTypes (visitedSets, col);
}
diff --git a/Mono.Addins/Mono.Addins.mdp b/Mono.Addins/Mono.Addins.mdp
index ca863bb..f79d80d 100644
--- a/Mono.Addins/Mono.Addins.mdp
+++ b/Mono.Addins/Mono.Addins.mdp
@@ -96,5 +96,4 @@
<AsmRefVar Sync="True" Name="DLL_REFERENCES" />
<ProjectRefVar Sync="True" Name="PROJECT_REFERENCES" />
</MonoDevelop.Autotools.MakefileInfo>
- <Deployment.LinuxDeployData scriptName="mono.addins" />
</Project> \ No newline at end of file
diff --git a/Mono.Addins/Mono.Addins/Addin.cs b/Mono.Addins/Mono.Addins/Addin.cs
index 0c0d6e9..2706988 100644
--- a/Mono.Addins/Mono.Addins/Addin.cs
+++ b/Mono.Addins/Mono.Addins/Addin.cs
@@ -42,7 +42,6 @@ namespace Mono.Addins
AddinInfo addin;
string configFile;
string sourceFile;
- string hostId;
WeakReference desc;
AddinDatabase database;
@@ -52,15 +51,12 @@ namespace Mono.Addins
configFile = file;
}
- internal Addin (AddinDatabase database, string hostId, string hostSourceFile)
- {
- this.database = database;
- this.hostId = hostId;
- this.sourceFile = hostSourceFile;
- }
-
public string Id {
- get { return this.AddinInfo.Id; }
+ get {
+ if (configFile != null)
+ return Path.GetFileNameWithoutExtension (configFile);
+ return this.AddinInfo.Id;
+ }
}
public string Namespace {
@@ -102,12 +98,12 @@ namespace Mono.Addins
}
public bool Enabled {
- get { return AddinInfo.IsRoot ? true : database.IsAddinEnabled (AddinInfo.Id, true); }
+ get { return AddinInfo.IsRoot ? true : database.IsAddinEnabled (Description.Domain, AddinInfo.Id, true); }
set {
if (value)
- database.EnableAddin (AddinInfo.Id, true);
+ database.EnableAddin (Description.Domain, AddinInfo.Id, true);
else
- database.DisableAddin (AddinInfo.Id);
+ database.DisableAddin (Description.Domain, AddinInfo.Id);
}
}
@@ -143,13 +139,9 @@ namespace Mono.Addins
if (d != null)
return d;
}
-
+
AddinDescription m;
-
- if (hostId != null)
- database.GetHostDescription (null, hostId, sourceFile, out m);
- else
- database.ReadAddinDescription (null, configFile, out m);
+ database.ReadAddinDescription (null, configFile, out m);
if (m == null)
throw new InvalidOperationException ("Could not read add-in description");
@@ -162,7 +154,7 @@ namespace Mono.Addins
}
}
-
+ // returns -1 if v1 > v2
public static int CompareVersions (string v1, string v2)
{
string[] a1 = v1.Split ('.');
diff --git a/Mono.Addins/Mono.Addins/AddinManager.cs b/Mono.Addins/Mono.Addins/AddinManager.cs
index a6c0261..4f7ae4b 100644
--- a/Mono.Addins/Mono.Addins/AddinManager.cs
+++ b/Mono.Addins/Mono.Addins/AddinManager.cs
@@ -62,8 +62,11 @@ namespace Mono.Addins
if (initialized)
return;
- startupDirectory = new Uri (Assembly.GetCallingAssembly ().CodeBase).LocalPath;
- startupDirectory = Path.GetDirectoryName (startupDirectory);
+ Assembly asm = Assembly.GetEntryAssembly ();
+ if (asm == null) asm = Assembly.GetCallingAssembly ();
+ string asmFile = new Uri (asm.CodeBase).LocalPath;
+
+ startupDirectory = Path.GetDirectoryName (asmFile);
string customDir = Environment.GetEnvironmentVariable ("MONO_ADDINS_REGISTRY");
if (customDir != null && customDir.Length > 0)
@@ -74,9 +77,6 @@ namespace Mono.Addins
else
registry = new AddinRegistry (configDir, startupDirectory);
- Assembly asm = Assembly.GetEntryAssembly ();
- if (asm == null) asm = Assembly.GetCallingAssembly ();
- string asmFile = new Uri (asm.CodeBase).LocalPath;
if (registry.CreateHostAddinsFile (asmFile))
registry.Update (new ConsoleProgressStatus (false));
diff --git a/Mono.Addins/Mono.Addins/AddinRegistry.cs b/Mono.Addins/Mono.Addins/AddinRegistry.cs
index 363587b..11a6d9f 100644
--- a/Mono.Addins/Mono.Addins/AddinRegistry.cs
+++ b/Mono.Addins/Mono.Addins/AddinRegistry.cs
@@ -42,6 +42,8 @@ namespace Mono.Addins
AddinDatabase database;
StringCollection addinDirs;
string basePath;
+ string currentDomain;
+ string startupDirectory;
public AddinRegistry (string registryPath): this (registryPath, null)
{
@@ -53,6 +55,11 @@ namespace Mono.Addins
database = new AddinDatabase (this);
addinDirs = new StringCollection ();
addinDirs.Add (Path.Combine (basePath, "addins"));
+ if (startupDirectory != null) {
+ currentDomain = database.GetFolderDomain (null, startupDirectory);
+ this.startupDirectory = startupDirectory;
+ } else
+ currentDomain = AddinDatabase.GlobalDomain;
}
public static AddinRegistry GetGlobalRegistry ()
@@ -96,23 +103,23 @@ namespace Mono.Addins
public Addin GetAddin (string id)
{
- return database.GetInstalledAddin (id);
+ return database.GetInstalledAddin (currentDomain, id);
}
public Addin GetAddin (string id, bool exactVersionMatch)
{
- return database.GetInstalledAddin (id, exactVersionMatch);
+ return database.GetInstalledAddin (currentDomain, id, exactVersionMatch);
}
public Addin[] GetAddins ()
{
- ArrayList list = database.GetInstalledAddins ();
+ ArrayList list = database.GetInstalledAddins (currentDomain, AddinType.Addin);
return (Addin[]) list.ToArray (typeof(Addin));
}
public Addin[] GetAddinRoots ()
{
- ArrayList list = database.GetAddinRoots ();
+ ArrayList list = database.GetInstalledAddins (currentDomain, AddinType.Root);
return (Addin[]) list.ToArray (typeof(Addin));
}
@@ -153,17 +160,17 @@ namespace Mono.Addins
public bool IsAddinEnabled (string id)
{
- return database.IsAddinEnabled (id);
+ return database.IsAddinEnabled (currentDomain, id);
}
public void EnableAddin (string id)
{
- database.EnableAddin (id, true);
+ database.EnableAddin (currentDomain, id, true);
}
public void DisableAddin (string id)
{
- database.DisableAddin (id);
+ database.DisableAddin (currentDomain, id);
}
public void DumpFile (string file)
@@ -178,22 +185,26 @@ namespace Mono.Addins
public void Update (IProgressStatus monitor)
{
- database.Update (monitor);
+ database.Update (monitor, currentDomain);
+ if (startupDirectory != null)
+ currentDomain = database.GetFolderDomain (null, startupDirectory);
}
public void Rebuild (IProgressStatus monitor)
{
- database.Repair (monitor);
+ database.Repair (monitor, currentDomain);
+ if (startupDirectory != null)
+ currentDomain = database.GetFolderDomain (null, startupDirectory);
}
internal Addin GetAddinForHostAssembly (string filePath)
{
- return database.GetAddinForHostAssembly (filePath);
+ return database.GetAddinForHostAssembly (currentDomain, filePath);
}
internal bool AddinDependsOn (string id1, string id2)
{
- return database.AddinDependsOn (id1, id2);
+ return database.AddinDependsOn (currentDomain, id1, id2);
}
internal void ScanFolders (IProgressStatus monitor, string folderToScan, StringCollection filesToIgnore)
@@ -248,7 +259,9 @@ namespace Mono.Addins
tw.Formatting = Formatting.Indented;
tw.WriteStartElement ("Addins");
tw.WriteAttributeString ("host-reference", hostFile);
- tw.WriteElementString ("Directory", Path.GetDirectoryName (hostFile));
+ tw.WriteStartElement ("Directory");
+ tw.WriteAttributeString ("shared", "false");
+ tw.WriteString (Path.GetDirectoryName (hostFile));
tw.WriteEndElement ();
tw.Close ();
}
diff --git a/Mono.Addins/Mono.Addins/AddinSessionService.cs b/Mono.Addins/Mono.Addins/AddinSessionService.cs
index 6711537..6aec5c2 100644
--- a/Mono.Addins/Mono.Addins/AddinSessionService.cs
+++ b/Mono.Addins/Mono.Addins/AddinSessionService.cs
@@ -337,7 +337,7 @@ namespace Mono.Addins
if (ainfo == null)
return;
}
- InsertAddin (null, ainfo);
+ LoadAddin (null, ainfo.Id, false);
}
}
}