From 3e7560380f0f92eb60945f89c9140aaf7350dc7a Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 23 Feb 2006 20:36:44 +0000 Subject: [PATCH] Conditions are now supported in the section of the .addin files. This allows choosing different assemblies based on properties like ${Platform} (Win32 or Win64). The new element can be used to disable AddIns completely based on conditions, e.g. when a platform is not supported at all. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1177 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../AddInManager/Project/Src/AddInControl.cs | 3 + .../AddInManager/Project/Src/ManagerForm.cs | 9 +- .../Project/ICSharpCode.Svn.addin | 5 +- .../Core/Project/Src/AddInTree/AddIn/AddIn.cs | 35 ++++--- .../Core/Project/Src/AddInTree/AddIn/Codon.cs | 24 +---- .../Project/Src/AddInTree/AddIn/Condition.cs | 17 +++- .../Src/AddInTree/AddIn/ExtensionPath.cs | 5 +- .../Project/Src/AddInTree/AddIn/Runtime.cs | 99 ++++++++++++++----- .../Project/Src/AddInTree/AddInManager.cs | 3 +- .../Core/Project/Src/AddInTree/AddInTree.cs | 21 ++++ .../Src/Services/StringParser/StringParser.cs | 9 ++ 11 files changed, 163 insertions(+), 67 deletions(-) diff --git a/src/AddIns/Misc/AddInManager/Project/Src/AddInControl.cs b/src/AddIns/Misc/AddInManager/Project/Src/AddInControl.cs index bb3598ae7b..856178c25c 100644 --- a/src/AddIns/Misc/AddInManager/Project/Src/AddInControl.cs +++ b/src/AddIns/Misc/AddInManager/Project/Src/AddInControl.cs @@ -182,6 +182,9 @@ namespace ICSharpCode.AddInManager case AddInAction.DependencyError: textBrush = Brushes.Red; return ResourceService.GetString("AddInManager.AddInDependencyFailed"); + case AddInAction.CustomError: + textBrush = Brushes.Red; + return StringParser.Parse(addIn.CustomErrorMessage); default: textBrush = Brushes.Yellow; return addIn.Action.ToString(); diff --git a/src/AddIns/Misc/AddInManager/Project/Src/ManagerForm.cs b/src/AddIns/Misc/AddInManager/Project/Src/ManagerForm.cs index 9f319e2cc6..ac09ae6710 100644 --- a/src/AddIns/Misc/AddInManager/Project/Src/ManagerForm.cs +++ b/src/AddIns/Misc/AddInManager/Project/Src/ManagerForm.cs @@ -199,6 +199,13 @@ namespace ICSharpCode.AddInManager List selected; AddInAction selectedAction; + static bool IsErrorAction(AddInAction action) + { + return action == AddInAction.DependencyError + || action == AddInAction.InstalledTwice + || action == AddInAction.CustomError; + } + void UpdateActionBox() { ignoreFocusChange = true; @@ -227,7 +234,7 @@ namespace ICSharpCode.AddInManager break; } allEnabled &= addIn.Action == AddInAction.Enable; - if (addIn.Action == AddInAction.DependencyError || addIn.Action == AddInAction.InstalledTwice) + if (IsErrorAction(addIn.Action)) hasErrors = true; else allDisabled &= addIn.Action == AddInAction.Disable; diff --git a/src/AddIns/Misc/SubversionAddIn/Project/ICSharpCode.Svn.addin b/src/AddIns/Misc/SubversionAddIn/Project/ICSharpCode.Svn.addin index 0595034848..94297dfd2c 100644 --- a/src/AddIns/Misc/SubversionAddIn/Project/ICSharpCode.Svn.addin +++ b/src/AddIns/Misc/SubversionAddIn/Project/ICSharpCode.Svn.addin @@ -8,7 +8,10 @@ - + + + + diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs index 3f098f1efc..b94f810546 100644 --- a/src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs @@ -50,6 +50,24 @@ namespace ICSharpCode.Core return "[AddIn: " + Name + "]"; } + string customErrorMessage; + + /// + /// Gets the message of a custom load error. Used only when AddInAction is set to CustomError. + /// + public string CustomErrorMessage { + get { + return customErrorMessage; + } + internal set { + if (value != null) { + Enabled = false; + Action = AddInAction.CustomError; + } + customErrorMessage = value; + } + } + /// /// Action to execute when the application is restarted. /// @@ -136,7 +154,7 @@ namespace ICSharpCode.Core { } - static void SetupAddIn(XmlTextReader reader, AddIn addIn, string hintPath) + static void SetupAddIn(XmlReader reader, AddIn addIn, string hintPath) { while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element && reader.IsStartElement()) { @@ -160,20 +178,7 @@ namespace ICSharpCode.Core break; case "Runtime": if (!reader.IsEmptyElement) { - while (reader.Read()){ - if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "Runtime") { - break; - } - if (reader.NodeType == XmlNodeType.Element && reader.IsStartElement()) { - switch (reader.LocalName) { - case "Import": - addIn.runtimes.Add(Runtime.Read(addIn, reader, hintPath)); - break; - default: - throw new AddInLoadException("Unknown node in runtime section :" + reader.LocalName); - } - } - } + Runtime.ReadSection(reader, addIn, hintPath); } break; case "Include": diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/Codon.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/Codon.cs index 82de9436f5..0404345735 100644 --- a/src/Main/Core/Project/Src/AddInTree/AddIn/Codon.cs +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/Codon.cs @@ -92,31 +92,17 @@ namespace ICSharpCode.Core public ConditionFailedAction GetFailedAction(object caller) { - ConditionFailedAction action = ConditionFailedAction.Nothing; - foreach (ICondition condition in conditions) { - try { - if (!condition.IsValid(caller)) { - if (condition.Action == ConditionFailedAction.Disable) { - action = ConditionFailedAction.Disable; - } else { - return action = ConditionFailedAction.Exclude; - } - } - } catch { - LoggingService.Error("Exception while getting failed action from " + addIn.FileName); - throw; - } - } - return action; + return Condition.GetFailedAction(conditions, caller); } -// + +// // public void BinarySerialize(BinaryWriter writer) // { // writer.Write(AddInTree.GetNameOffset(name)); // writer.Write(AddInTree.GetAddInOffset(addIn)); // properties.BinarySerialize(writer); // } -// +// public object BuildItem(object owner, ArrayList subItems) { try { @@ -137,7 +123,7 @@ namespace ICSharpCode.Core { return String.Format("[Codon: name = {0}, addIn={1}]", name, - addIn.FileName); + addIn.FileName); } } } diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/Condition.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/Condition.cs index 1c4418e015..bf656de4bf 100644 --- a/src/Main/Core/Project/Src/AddInTree/AddIn/Condition.cs +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/Condition.cs @@ -93,7 +93,7 @@ namespace ICSharpCode.Core case "Condition": condition = Condition.Read(reader); goto exit; - } + } break; } } @@ -135,5 +135,20 @@ namespace ICSharpCode.Core } return conditions.ToArray(); } + + public static ConditionFailedAction GetFailedAction(IEnumerable conditionList, object caller) + { + ConditionFailedAction action = ConditionFailedAction.Nothing; + foreach (ICondition condition in conditionList) { + if (!condition.IsValid(caller)) { + if (condition.Action == ConditionFailedAction.Disable) { + action = ConditionFailedAction.Disable; + } else { + return ConditionFailedAction.Exclude; + } + } + } + return action; + } } } diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/ExtensionPath.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/ExtensionPath.cs index 98428e1322..461bbfc7f7 100644 --- a/src/Main/Core/Project/Src/AddInTree/AddIn/ExtensionPath.cs +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/ExtensionPath.cs @@ -44,7 +44,7 @@ namespace ICSharpCode.Core this.name = name; } - public static void SetUp(ExtensionPath extensionPath, XmlTextReader reader, string endElement) + public static void SetUp(ExtensionPath extensionPath, XmlReader reader, string endElement) { Stack conditionStack = new Stack(); while (reader.Read()) { @@ -59,8 +59,7 @@ namespace ICSharpCode.Core case XmlNodeType.Element: string elementName = reader.LocalName; if (elementName == "Condition") { - ICondition newCondition = Condition.Read(reader); - conditionStack.Push(newCondition); + conditionStack.Push(Condition.Read(reader)); } else if (elementName == "ComplexCondition") { conditionStack.Push(Condition.ReadComplexCondition(reader)); } else { diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/Runtime.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/Runtime.cs index 8c10c98062..3747f23aae 100644 --- a/src/Main/Core/Project/Src/AddInTree/AddIn/Runtime.cs +++ b/src/Main/Core/Project/Src/AddInTree/AddIn/Runtime.cs @@ -15,11 +15,25 @@ namespace ICSharpCode.Core { public class Runtime { - string hintPath; - string assembly; - Assembly loadedAssembly = null; - List definedDoozers = new List(1); - List definedConditionEvaluators = new List(1); + string hintPath; + string assembly; + Assembly loadedAssembly = null; + + IList definedDoozers = new List(); + IList definedConditionEvaluators = new List(); + ICondition[] conditions; + bool isActive = true; + bool isAssemblyLoaded; + + public bool IsActive { + get { + if (conditions != null) { + isActive = Condition.GetFailedAction(conditions, this) == ConditionFailedAction.Nothing; + conditions = null; + } + return isActive; + } + } public Runtime(string assembly, string hintPath) { @@ -33,8 +47,6 @@ namespace ICSharpCode.Core } } - bool isAssemblyLoaded; - public Assembly LoadedAssembly { get { if (!isAssemblyLoaded) { @@ -79,13 +91,13 @@ namespace ICSharpCode.Core } } - public List DefinedDoozers { + public IList DefinedDoozers { get { return definedDoozers; } } - public List DefinedConditionEvaluators { + public IList DefinedConditionEvaluators { get { return definedConditionEvaluators; } @@ -93,18 +105,62 @@ namespace ICSharpCode.Core public object CreateInstance(string instance) { - Assembly asm = LoadedAssembly; - if (asm == null) + if (IsActive) { + Assembly asm = LoadedAssembly; + if (asm == null) + return null; + return asm.CreateInstance(instance); + } else { return null; - return asm.CreateInstance(instance); + } } - internal static Runtime Read(AddIn addIn, XmlTextReader reader, string hintPath) + internal static void ReadSection(XmlReader reader, AddIn addIn, string hintPath) + { + Stack conditionStack = new Stack(); + while (reader.Read()) { + switch (reader.NodeType) { + case XmlNodeType.EndElement: + if (reader.LocalName == "Condition" || reader.LocalName == "ComplexCondition") { + conditionStack.Pop(); + } else if (reader.LocalName == "Runtime") { + return; + } + break; + case XmlNodeType.Element: + switch (reader.LocalName) { + case "Condition": + conditionStack.Push(Condition.Read(reader)); + break; + case "ComplexCondition": + conditionStack.Push(Condition.ReadComplexCondition(reader)); + break; + case "Import": + addIn.Runtimes.Add(Runtime.Read(addIn, reader, hintPath, conditionStack)); + break; + case "DisableAddIn": + if (Condition.GetFailedAction(conditionStack, addIn) == ConditionFailedAction.Nothing) { + // The DisableAddIn node not was not disabled by a condition + addIn.CustomErrorMessage = reader.GetAttribute("message"); + } + break; + default: + throw new AddInLoadException("Unknown node in runtime section :" + reader.LocalName); + } + break; + } + } + } + + internal static Runtime Read(AddIn addIn, XmlReader reader, string hintPath, Stack conditionStack) { if (reader.AttributeCount != 1) { throw new AddInLoadException("Import node requires ONE attribute."); } Runtime runtime = new Runtime(reader.GetAttribute(0), hintPath); + if (conditionStack.Count > 0) { + runtime.conditions = conditionStack.ToArray(); + } if (!reader.IsEmptyElement) { while (reader.Read()) { switch (reader.NodeType) { @@ -121,24 +177,13 @@ namespace ICSharpCode.Core if (!reader.IsEmptyElement) { throw new AddInLoadException("Doozer nodes must be empty!"); } - LazyLoadDoozer lazyLoadDoozer = new LazyLoadDoozer(addIn, properties); - - if (AddInTree.Doozers.ContainsKey(lazyLoadDoozer.Name)) { - throw new AddInLoadException("Duplicate doozer: " + lazyLoadDoozer.Name); - } - AddInTree.Doozers.Add(lazyLoadDoozer.Name, lazyLoadDoozer); - runtime.definedDoozers.Add(properties); + runtime.definedDoozers.Add(new LazyLoadDoozer(addIn, properties)); break; case "ConditionEvaluator": if (!reader.IsEmptyElement) { throw new AddInLoadException("ConditionEvaluator nodes must be empty!"); } - LazyConditionEvaluator lazyLoadConditionEvaluator = new LazyConditionEvaluator(addIn, properties); - if (AddInTree.ConditionEvaluators.ContainsKey(lazyLoadConditionEvaluator.Name)) { - throw new AddInLoadException("Duplicate condition evaluator: " + lazyLoadConditionEvaluator.Name); - } - AddInTree.ConditionEvaluators.Add(lazyLoadConditionEvaluator.Name, lazyLoadConditionEvaluator); - runtime.definedConditionEvaluators.Add(properties); + runtime.definedConditionEvaluators.Add(new LazyConditionEvaluator(addIn, properties)); break; default: throw new AddInLoadException("Unknown node in Import section:" + nodeName); @@ -147,6 +192,8 @@ namespace ICSharpCode.Core } } } + runtime.definedDoozers = (runtime.definedDoozers as List).AsReadOnly(); + runtime.definedConditionEvaluators = (runtime.definedConditionEvaluators as List).AsReadOnly(); return runtime; } } diff --git a/src/Main/Core/Project/Src/AddInTree/AddInManager.cs b/src/Main/Core/Project/Src/AddInTree/AddInManager.cs index 6694bfd377..f7e3ad58fd 100644 --- a/src/Main/Core/Project/Src/AddInTree/AddInManager.cs +++ b/src/Main/Core/Project/Src/AddInTree/AddInManager.cs @@ -21,7 +21,8 @@ namespace ICSharpCode.Core Uninstall, Update, InstalledTwice, - DependencyError + DependencyError, + CustomError } public static class AddInManager diff --git a/src/Main/Core/Project/Src/AddInTree/AddInTree.cs b/src/Main/Core/Project/Src/AddInTree/AddInTree.cs index 72ef62a91f..c7f5bf4bfa 100644 --- a/src/Main/Core/Project/Src/AddInTree/AddInTree.cs +++ b/src/Main/Core/Project/Src/AddInTree/AddInTree.cs @@ -165,6 +165,23 @@ namespace ICSharpCode.Core AddExtensionPath(path); } + foreach (Runtime runtime in addIn.Runtimes) { + if (runtime.IsActive) { + foreach (LazyLoadDoozer doozer in runtime.DefinedDoozers) { + if (AddInTree.Doozers.ContainsKey(doozer.Name)) { + throw new AddInLoadException("Duplicate doozer: " + doozer.Name); + } + AddInTree.Doozers.Add(doozer.Name, doozer); + } + foreach (LazyConditionEvaluator condition in runtime.DefinedConditionEvaluators) { + if (AddInTree.ConditionEvaluators.ContainsKey(condition.Name)) { + throw new AddInLoadException("Duplicate condition evaluator: " + condition.Name); + } + AddInTree.ConditionEvaluators.Add(condition.Name, condition); + } + } + } + string addInRoot = Path.GetDirectoryName(addIn.FileName); foreach(string bitmapResource in addIn.BitmapResources) { @@ -245,6 +262,10 @@ namespace ICSharpCode.Core Dictionary addInDict = new Dictionary(); foreach (string fileName in addInFiles) { AddIn addIn = AddIn.Load(fileName); + if (addIn.Action == AddInAction.CustomError) { + list.Add(addIn); + continue; + } addIn.Enabled = true; if (disabledAddIns != null && disabledAddIns.Count > 0) { foreach (string name in addIn.Manifest.Identities.Keys) { diff --git a/src/Main/Core/Project/Src/Services/StringParser/StringParser.cs b/src/Main/Core/Project/Src/Services/StringParser/StringParser.cs index f5a20c42d9..64f68e4f68 100644 --- a/src/Main/Core/Project/Src/Services/StringParser/StringParser.cs +++ b/src/Main/Core/Project/Src/Services/StringParser/StringParser.cs @@ -52,6 +52,15 @@ namespace ICSharpCode.Core propertyObjects["exe"] = FileVersionInfo.GetVersionInfo(exeName); } properties["USER"] = Environment.UserName; + + // Maybe test for Mono? + if (IntPtr.Size == 4) { + properties["Platform"] = "Win32"; + } else if (IntPtr.Size == 8) { + properties["Platform"] = "Win64"; + } else { + properties["Platform"] = "unknown"; + } } public static string Parse(string input)