[Monodevelop-patches-list] r1045 - branches/MonoDevelop-playground/src/Main/StartUp
commit-watcher at mono-cvs.ximian.com
commit-watcher at mono-cvs.ximian.com
Fri Feb 27 06:18:26 EST 2004
Author: jzwart
Date: 2004-02-27 06:18:26 -0500 (Fri, 27 Feb 2004)
New Revision: 1045
Added:
branches/MonoDevelop-playground/src/Main/StartUp/BasePlugin.cs
branches/MonoDevelop-playground/src/Main/StartUp/ICommand.cs
branches/MonoDevelop-playground/src/Main/StartUp/MonoDevelop.cs
branches/MonoDevelop-playground/src/Main/StartUp/monodevelop.exe.config.in
Removed:
branches/MonoDevelop-playground/src/Main/StartUp/Dialogs/
Modified:
branches/MonoDevelop-playground/src/Main/StartUp/Makefile.am
Log:
First part of the addin refactoring. Lots more to follow.
Added: branches/MonoDevelop-playground/src/Main/StartUp/BasePlugin.cs
===================================================================
--- branches/MonoDevelop-playground/src/Main/StartUp/BasePlugin.cs 2004-02-26 20:24:49 UTC (rev 1044)
+++ branches/MonoDevelop-playground/src/Main/StartUp/BasePlugin.cs 2004-02-27 11:18:26 UTC (rev 1045)
@@ -0,0 +1,39 @@
+//
+// BasePlugin.cs: Abstract plugin class from which all plugins must inherit.
+//
+// Author:
+// Jeroen Zwartepoorte <jeroen at xs4all.nl>
+//
+// (C) Copyright Jeroen Zwartepoorte 2004
+//
+
+namespace MonoDevelop {
+ abstract public class BasePlugin {
+ abstract public string Author {
+ get;
+ }
+
+ abstract public string Copyright {
+ get;
+ }
+
+ abstract public string Description {
+ get;
+ }
+
+ abstract public string Name {
+ get;
+ }
+
+ abstract public string Url {
+ get;
+ }
+
+ abstract public string Version {
+ get;
+ }
+
+ abstract public bool InitializePlugin (byte major, byte minor);
+ abstract public void FinalizePlugin ();
+ }
+}
Added: branches/MonoDevelop-playground/src/Main/StartUp/ICommand.cs
===================================================================
--- branches/MonoDevelop-playground/src/Main/StartUp/ICommand.cs 2004-02-26 20:24:49 UTC (rev 1044)
+++ branches/MonoDevelop-playground/src/Main/StartUp/ICommand.cs 2004-02-27 11:18:26 UTC (rev 1045)
@@ -0,0 +1,24 @@
+//
+// ICommand.cs: Interface for handling command-line parameters.
+//
+// Author:
+// Jeroen Zwartepoorte <jeroen at xs4all.nl>
+//
+// (C) Copyright Jeroen Zwartepoorte 2004
+//
+
+using System;
+
+namespace MonoDevelop {
+ public interface ICommand {
+ string CommandDescription {
+ get;
+ }
+
+ bool TakesCommandArguments {
+ get;
+ }
+
+ void InvokeCommand (string[] args);
+ }
+}
Modified: branches/MonoDevelop-playground/src/Main/StartUp/Makefile.am
===================================================================
--- branches/MonoDevelop-playground/src/Main/StartUp/Makefile.am 2004-02-26 20:24:49 UTC (rev 1044)
+++ branches/MonoDevelop-playground/src/Main/StartUp/Makefile.am 2004-02-27 11:18:26 UTC (rev 1045)
@@ -1,52 +1,22 @@
-BASEDIR=../../..
+monodevelopdir = $(bindir)
+monodevelop_DATA = monodevelop.exe monodevelop.exe.config
+CLEANFILES = monodevelop.exe monodevelop.exe.config
+CSC=mcs
-FILES= \
-./SharpDevelopMain.cs \
-./Dialogs/AddInTreeSettingsHandler.cs \
-./Dialogs/ExceptionBox.cs \
-./AssemblyInfo.cs
+monodevelop_sources = \
+ MonoDevelop.cs \
+ BasePlugin.cs \
+ ICommand.cs \
+ AssemblyInfo.cs
+
+monodevelop_assemblies = -r:log4net.dll
-RESOURCES= \
-/resource:$(BASEDIR)/data/resources/StringResources.fr.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.cn-gb.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.jp.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.nl.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.pl.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.ro.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.pt.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.ru.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.goisern.resources \
-/resource:$(BASEDIR)/data/resources/BitmapResources.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.se.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.es.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.cz.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.kr.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.it.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.bg.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.de.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.cn-big.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.dk.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.resources,StringResources.resources \
-/resource:$(BASEDIR)/data/resources/StringResources.br.resources \
-/resource:$(BASEDIR)/data/resources/SplashScreen.png,SplashScreen.png
+monodevelop.exe: $(monodevelop_sources)
+ $(CSC) -debug -out:monodevelop.exe $(monodevelop_sources) $(monodevelop_assemblies)
-DLL=../../../build/bin/MonoDevelop.exe
+monodevelop.exe.config: monodevelop.exe.config.in
+ sed -e 's^\@monodevelop_plugin_dir\@^$(monodevelop_plugin_dir)^g' -e 's^\@monodevelop_ui_dir\@^$(monodevelop_ui_dir)^g' < $(srcdir)/monodevelop.exe.config.in > monodevelop.exe.config
-all: $(DLL)
-
-$(DLL): $(FILES)
- @ mcs /debug /out:$(DLL) /r:System.Drawing.dll \
- /r:../../../build/bin/MonoDevelop.Core.dll \
- /r:../../../build/bin/MonoDevelop.Base.dll \
- /r:glib-sharp.dll \
- /define:GTK /r:gtk-sharp.dll /r:gdk-sharp.dll \
- /r:gnome-sharp.dll \
- $(RESOURCES) $(FILES)
-
-assemblydir = $(libdir)/monodevelop/bin
-assembly_DATA = $(DLL)
-
-CLEANFILES=$(DLL)
-
-EXTRA_DIST = $(FILES)
-
+EXTRA_DIST = \
+ $(monodevelop_sources) \
+ monodevelop.exe.config.in
Added: branches/MonoDevelop-playground/src/Main/StartUp/MonoDevelop.cs
===================================================================
--- branches/MonoDevelop-playground/src/Main/StartUp/MonoDevelop.cs 2004-02-26 20:24:49 UTC (rev 1044)
+++ branches/MonoDevelop-playground/src/Main/StartUp/MonoDevelop.cs 2004-02-27 11:18:26 UTC (rev 1045)
@@ -0,0 +1,387 @@
+//
+// MonoDevelop.cs: Entrypoint for application. Loads plugins from .plugin files.
+//
+// Author:
+// Jeroen Zwartepoorte <jeroen at xs4all.nl>
+//
+// (C) Copyright Jeroen Zwartepoorte 2004
+//
+// TODO
+// - Add a standard --verbose option that sets log4net's level to ALL.
+//
+
+using System;
+using System.Collections;
+using System.Configuration;
+using System.IO;
+using System.Reflection;
+using System.Xml;
+
+using log4net;
+using log4net.Config;
+
+namespace MonoDevelop {
+ public class PluginInfo {
+ private string assembly;
+ private string name;
+ private ArrayList dependencies;
+ private int resolvePass;
+ private int discovered;
+ private int finished;
+ private BasePlugin instance;
+ private bool active;
+
+ public PluginInfo (string assembly, string name) {
+ this.assembly = assembly;
+ this.name = name;
+ dependencies = new ArrayList ();
+ resolvePass = -1;
+ discovered = -1;
+ finished = -1;
+ instance = null;
+ active = false;
+ }
+
+ public string Assembly {
+ get {
+ return assembly;
+ }
+ }
+
+ public string Name {
+ get {
+ return name;
+ }
+ }
+
+ public ArrayList Dependencies {
+ get {
+ return dependencies;
+ }
+ }
+
+ public int ResolvePass {
+ get {
+ return resolvePass;
+ }
+ set {
+ resolvePass = value;
+ }
+ }
+
+ public int Discovered {
+ get {
+ return discovered;
+ }
+ set {
+ discovered = value;
+ }
+ }
+
+ public int Finished {
+ get {
+ return finished;
+ }
+ set {
+ finished = value;
+ }
+ }
+
+ public BasePlugin Instance {
+ get {
+ return instance;
+ }
+ set {
+ instance = value;
+ }
+ }
+
+ public bool Active {
+ get {
+ return active;
+ }
+ set {
+ active = value;
+ }
+ }
+ }
+
+ class NameComparer : IComparer
+ {
+ public int Compare (Object obj1, Object obj2)
+ {
+ string className = (string)obj1;
+ PluginInfo plugin = (PluginInfo)obj2;
+ return String.Compare (className, plugin.Name);
+ }
+ }
+
+ public class MonoDevelop
+ {
+ private static readonly ILog log = LogManager.GetLogger (typeof (MonoDevelop));
+ private static NameComparer nameComparer = new NameComparer ();
+ private static int time = 0;
+ private static ArrayList plugins;
+ private static Hashtable commands = new Hashtable ();
+ private static ICommand defaultCommand = null;
+
+ // Configure log4net using the .config file.
+ [assembly: log4net.Config.DOMConfigurator(Watch=true)]
+
+ public static PluginInfo[] AvailablePlugins {
+ get {
+ PluginInfo[] result = new PluginInfo[plugins.Count];
+ plugins.CopyTo (result);
+ return result;
+ }
+ }
+
+ //
+ // Registers a command handler for a particular command line option.
+ // An option value of null is used for the "default" handler. Set both
+ // parameters to null if you want to disable the default handler.
+ //
+ public static void RegisterCommand (string option, ICommand cmd)
+ {
+ if (option == null) {
+ defaultCommand = cmd;
+ } else {
+ if (commands.Contains (option))
+ log.Warn ("Command " + option + " is already registered");
+ else
+ commands.Add (option, cmd);
+ }
+ }
+
+ static void Main (string[] args)
+ {
+ log.Debug ("Starting MonoDevelop");
+
+ // Make a list of plugin directories.
+ ArrayList pluginDirs = new ArrayList ();
+ string path = ConfigurationSettings.AppSettings["pluginsPath"];
+ if (path == null) {
+ log.Error ("Unknown configuration property \"pluginsPath\"");
+ log.Error ("Your monodevelop.exe.config is likely broken");
+ log.Error ("Please reinstall MonoDevelop");
+ return;
+ }
+ pluginDirs.Add (path);
+
+ // Add directories from the $MONODEVELOP_PLUGIN_PATH environment var.
+ path = Environment.GetEnvironmentVariable ("MONODEVELOP_PLUGIN_PATH");
+ if (path != null) {
+ string[] dirs = path.Split (Path.DirectorySeparatorChar);
+ foreach (string dir in dirs)
+ pluginDirs.Add (dir);
+ }
+
+ // Scan for .plugin files in the plugin directories.
+ log.Debug ("Looking for .plugin files");
+ ArrayList pluginFiles = new ArrayList ();
+ foreach (string pluginDir in pluginDirs) {
+ if (!Directory.Exists (pluginDir))
+ continue;
+ log.Debug ("Scanning " + pluginDir);
+ DirectoryInfo di = new DirectoryInfo (pluginDir);
+ FileInfo[] files = di.GetFiles ("*.plugin");
+ pluginFiles.AddRange (files);
+ }
+ log.Debug ("" + pluginFiles.Count + " plugin file(s) found");
+
+ // Parse the .plugin files and build a list of plugins
+ // and dependencies.
+ plugins = new ArrayList ();
+ foreach (FileInfo file in pluginFiles) {
+ log.Debug ("Parsing " + file.FullName);
+ ParsePluginFile (file.FullName);
+ }
+
+ // Determine the order in which to load plugins.
+ SortedList loadOrder = ResolveDependencies ();
+
+ // Load the plugins in proper order from the loadOrder SortedList.
+ foreach (PluginInfo plugin in loadOrder.Values) {
+ try {
+ log.Debug ("Loading " + plugin.Name);
+ Assembly a = Assembly.LoadFrom (plugin.Assembly);
+ plugin.Instance = (BasePlugin) a.CreateInstance (plugin.Name);
+ if (plugin.Instance.InitializePlugin ((byte)1, (byte)0))
+ plugin.Active = true;
+ } catch (System.Exception e) {
+ log.Error ("Error loading " + plugin.Name, e);
+ continue;
+ }
+ }
+
+ // Check for --help argument.
+ if (Array.BinarySearch (args, "--help") >= 0) {
+ PrintHelp ();
+ return;
+ }
+
+ // If the first argument isn't a registered ICommand,
+ // then interpret all the arguments as input for the
+ // default command handler.
+ if (args.Length == 0 || !commands.Contains (args[0])) {
+ // Invoke the default ICommand.
+ if (defaultCommand == null) {
+ log.Error ("No default command handler registered; Exiting");
+ return;
+ } else {
+ defaultCommand.InvokeCommand (args);
+ }
+ } else {
+ // Parse the commandline arguments.
+ for (int i = 0; i < args.Length; i++) {
+ ICommand cmd = (ICommand)commands[args[i]];
+ if (cmd.TakesCommandArguments) {
+ ArrayList p = new ArrayList ();
+ while ((args.Length > i + 1) && !commands.Contains (args[i+1]))
+ p.Add (args[++i]);
+ string[] result = new string[p.Count];
+ p.CopyTo (result);
+ cmd.InvokeCommand (result);
+ } else {
+ cmd.InvokeCommand (null);
+ }
+ }
+ }
+
+ // At this point, the command handler has finished its task.
+ // Example: it has finished a --build command or the default
+ // command handler has returned from the GTK+ main loop.
+
+ // Finalize all plugins in the reverse order they were loaded.
+ for (int i = loadOrder.Count - 1; i >= 0; i--) {
+ PluginInfo plugin = (PluginInfo)loadOrder.GetByIndex (i);
+ plugin.Instance.FinalizePlugin ();
+ }
+ commands.Clear ();
+ loadOrder.Clear ();
+ plugins.Clear ();
+
+ // And exit.
+ log.Debug ("Exiting MonoDevelop");
+ }
+
+ //
+ // Output information about monodevelop's usage and possible commandline
+ // parameters to the console.
+ //
+ private static void PrintHelp ()
+ {
+ Console.WriteLine ("Usage is: monodevelop [options] files");
+ foreach (ICommand cmd in commands.Values)
+ Console.WriteLine (" {0}", cmd.CommandDescription);
+ Console.WriteLine ("");
+ }
+
+ //
+ // Parses a .plugin file and creates a new PluginInfo class with the
+ // attributes from the .plugin file.
+ //
+ private static void ParsePluginFile (string file)
+ {
+ XmlTextReader reader = new XmlTextReader (file);
+ PluginInfo plugin = null;
+ string assembly = null;
+
+ while (reader.Read ()) {
+ if (reader.NodeType == XmlNodeType.Element) {
+ switch (reader.Name) {
+ case "assembly":
+ assembly = reader.ReadElementString ();
+ break;
+ case "class":
+ plugin = new PluginInfo (assembly, reader["name"]);
+ plugins.Add (plugin);
+ break;
+ case "depends":
+ plugin.Dependencies.Add (reader.ReadElementString());
+ break;
+ }
+ }
+ }
+ }
+
+ //
+ // Returns the PluginInfo belonging to the specified className. Returns
+ // null if a matching PluginInfo wasn't found.
+ //
+ private static PluginInfo FindPlugin (ArrayList list, string className)
+ {
+ int idx = plugins.BinarySearch (className, nameComparer);
+
+ if (idx >= 0)
+ return (PluginInfo)list[idx];
+ else
+ return null;
+ }
+
+ //
+ // Resolve the plugin dependencies. Check for cycles and whether
+ // dependency classes exist. The end result will be that the loadOrder
+ // SortedList will contain the plugins in the order that they need to be
+ // loaded.
+ //
+ private static SortedList ResolveDependencies ()
+ {
+ time = 0;
+ int pass = 0;
+ SortedList result = new SortedList ();
+
+ foreach (PluginInfo plugin in plugins) {
+ if (plugin.ResolvePass == -1) {
+ if (!TraversePlugin (plugin, result, pass++))
+ log.Error ("Unable to load: " + plugin.Name);
+ }
+ }
+
+ return result;
+ }
+
+ //
+ // Traverse the graph using a Depth First Search and sort the plugins
+ // based on the "finished time". During each "pass", the ResolvePass
+ // attribute is set on each PluginInfo to detect when a cycle has
+ // occurred. When this happens, false will be returned through the
+ // recursion and the cycle will be excluded from the loadOrder list. The
+ // same occurs when a plugin depends on a class which is not listed in
+ // any .plugin file.
+ //
+ private static bool TraversePlugin (PluginInfo plugin,
+ SortedList order,
+ int pass)
+ {
+ plugin.ResolvePass = pass;
+ plugin.Discovered = ++time;
+
+ foreach (string className in plugin.Dependencies) {
+ PluginInfo child = FindPlugin (plugins, className);
+
+ // Check that the dependency class exists.
+ if (child == null) {
+ log.Error ("Class not found: " + className);
+ return false;
+ }
+
+ // Check for cycles in the dependency graph.
+ if (child.ResolvePass != pass) {
+ if (!TraversePlugin (child, order, pass)) {
+ log.Error ("Unable to load: " + child.Name);
+ return false;
+ }
+ } else {
+ log.Error ("Circular dependency: " + child.Name);
+ return false;
+ }
+ }
+
+ plugin.Finished = ++time;
+ order.Add (plugin.Finished, plugin);
+
+ return true;
+ }
+ }
+}
Added: branches/MonoDevelop-playground/src/Main/StartUp/monodevelop.exe.config.in
===================================================================
--- branches/MonoDevelop-playground/src/Main/StartUp/monodevelop.exe.config.in 2004-02-26 20:24:49 UTC (rev 1044)
+++ branches/MonoDevelop-playground/src/Main/StartUp/monodevelop.exe.config.in 2004-02-27 11:18:26 UTC (rev 1045)
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+ <appSettings>
+ <add key="pluginsPath" value="@scaffold_plugin_dir@"/>
+ <add key="uiPath" value="@scaffold_ui_dir@"/>
+ </appSettings>
+ <configSections>
+ <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
+ </configSections>
+ <log4net>
+ <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
+ <layout type="log4net.Layout.PatternLayout">
+ <param name="ConversionPattern" value="%-5p - %m%n"/>
+ </layout>
+ </appender>
+ <root>
+ <level value="ALL"/>
+ <appender-ref ref="ConsoleAppender"/>
+ </root>
+ </log4net>
+</configuration>
More information about the Monodevelop-patches-list
mailing list