Mantis#1647. Thank you very much, Sempuki for a patch that:

Updates the previous module loader work.
0.6.0-stable
Charles Krinke 2008-07-04 03:11:53 +00:00
parent ce5122ebf3
commit 23ec21e44a
6 changed files with 183 additions and 79 deletions

View File

@ -38,7 +38,7 @@ namespace OpenSim.Framework
public PluginNotInitialisedException (string msg) : base(msg) {}
public PluginNotInitialisedException (string msg, Exception e) : base(msg, e) {}
}
/// <summary>
/// This interface, describes a generic plugin
/// </summary>
@ -61,4 +61,20 @@ namespace OpenSim.Framework
/// </summary>
void Initialise();
}
/// <summary>
/// Any plugins which need to pass parameters to their initialisers must
/// inherit this class and use it to set the PluginLoader Initialiser property
/// </summary>
public class PluginInitialiserBase
{
// this would be a lot simpler if C# supported currying or typedefs
// default initialisation
public virtual void Initialise (IPlugin plugin)
{
plugin.Initialise();
}
}
}

View File

@ -37,11 +37,21 @@ namespace OpenSim.Framework
/// <summary>
/// Exception thrown if an incorrect number of plugins are loaded
/// </summary>
public class PluginCountInvalidException : Exception
public class PluginConstraintViolatedException : Exception
{
public PluginCountInvalidException () : base() {}
public PluginCountInvalidException (string msg) : base(msg) {}
public PluginCountInvalidException (string msg, Exception e) : base(msg, e) {}
public PluginConstraintViolatedException () : base() {}
public PluginConstraintViolatedException (string msg) : base(msg) {}
public PluginConstraintViolatedException (string msg, Exception e) : base(msg, e) {}
}
/// <summary>
/// Classes wishing to impose constraints on plugin loading must implement
/// this class and pass it to PluginLoader AddConstraint()
/// </summary>
public interface IPluginConstraint
{
bool Fail (string extpoint);
string Message { get; }
}
/// <summary>
@ -49,26 +59,42 @@ namespace OpenSim.Framework
/// </summary>
public class PluginLoader <T> : IDisposable where T : IPlugin
{
private struct Range
{
public int min;
public int max;
public Range (int n, int x) { min=n; max=x; }
}
private const int max_loadable_plugins = 10000;
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private List<T> loaded = new List<T>();
private List<string> extpoints = new List<string>();
private Dictionary<string,Range> constraints = new Dictionary<string,Range>();
private PluginInitialiserBase initialiser;
private Dictionary<string,IPluginConstraint> constraints
= new Dictionary<string,IPluginConstraint>();
public delegate void Initialiser (IPlugin p);
private void default_initialiser_ (IPlugin p) { p.Initialise(); }
private static readonly ILog log
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public PluginInitialiserBase Initialiser
{
set { initialiser = value; }
get { return initialiser; }
}
public List<T> Plugins
{
get { return loaded; }
}
public PluginLoader (string dir)
public PluginLoader ()
{
Initialiser = new PluginInitialiserBase();
}
public PluginLoader (PluginInitialiserBase init)
{
AddPluginDir (dir);
Initialiser = init;
}
public PluginLoader (PluginInitialiserBase init, string dir)
{
Initialiser = init;
AddPluginDir (dir);
}
public void AddPluginDir (string dir)
@ -84,65 +110,45 @@ namespace OpenSim.Framework
extpoints.Add (extpoint);
}
public void AddConstrainedExtensionPoint (string extpoint, int min, int max)
public void AddConstraint (string extpoint, IPluginConstraint cons)
{
constraints.Add (extpoint, new Range (min, max));
AddExtensionPoint (extpoint);
constraints.Add (extpoint, cons);
}
public void LoadAll (Initialiser initialise)
public void Load (string extpoint, string dir)
{
foreach (string pt in extpoints)
Load (pt, initialise);
AddPluginDir (dir);
AddExtensionPoint (extpoint);
Load();
}
public void Load (string extpoint)
{
Load (extpoint, default_initialiser_);
}
public void Load (string extpoint, Initialiser initialise)
{
int min = 0;
int max = max_loadable_plugins;
if (constraints.ContainsKey (extpoint))
{
min = constraints[extpoint].min;
max = constraints[extpoint].max;
}
Load (extpoint, initialise, min, max);
}
public void Load (string extpoint, Initialiser initialise, int min, int max)
public void Load ()
{
suppress_console_output_ (true);
AddinManager.Registry.Update (null);
suppress_console_output_ (false);
ExtensionNodeList ns = AddinManager.GetExtensionNodes(extpoint);
if ((ns.Count < min) || (ns.Count > max))
throw new PluginCountInvalidException
("The number of plugins for " + extpoint +
" is constrained to the interval [" + min + ", " + max + "]");
foreach (TypeExtensionNode n in ns)
foreach (string ext in extpoints)
{
T p = (T) n.CreateInstance();
initialise (p);
Plugins.Add (p);
if (constraints.ContainsKey (ext))
{
IPluginConstraint cons = constraints [ext];
if (cons.Fail (ext))
throw new PluginConstraintViolatedException (cons.Message);
}
log.Info("[PLUGINS]: Loading plugin " + n.Path);
ExtensionNodeList ns = AddinManager.GetExtensionNodes (ext);
foreach (TypeExtensionNode n in ns)
{
T p = (T) n.CreateInstance();
Initialiser.Initialise (p);
Plugins.Add (p);
log.Info("[PLUGINS]: Loading plugin " + n.Path);
}
}
}
public List<T> Plugins
{
get { return loaded; }
}
public void Dispose ()
{
foreach (T p in Plugins)
@ -174,6 +180,73 @@ namespace OpenSim.Framework
System.Console.SetOut(prev_console_);
}
}
}
public class PluginCountConstraint : IPluginConstraint
{
private int min;
private int max;
public PluginCountConstraint (int exact)
{
min = exact;
max = exact;
}
public PluginCountConstraint (int minimum, int maximum)
{
min = minimum;
max = maximum;
}
public string Message
{
get
{
return "The number of plugins is constrained to the interval ["
+ min + ", " + max + "]";
}
}
public bool Fail (string extpoint)
{
ExtensionNodeList ns = AddinManager.GetExtensionNodes (extpoint);
if ((ns.Count < min) || (ns.Count > max))
return true;
else
return false;
}
}
public class PluginFilenameConstraint : IPluginConstraint
{
private string filename;
public PluginFilenameConstraint (string name)
{
filename = name;
}
public string Message
{
get
{
return "The plugin must have the following name: " + filename;
}
}
public bool Fail (string extpoint)
{
ExtensionNodeList ns = AddinManager.GetExtensionNodes (extpoint);
if (ns.Count != 1)
return true;
string[] path = ns[0].Path.Split('/');
if (path [path.Length-1] == filename)
return false;
return true;
}
}
}

View File

@ -87,7 +87,7 @@ namespace OpenSim.Grid.GridServer
AddHttpHandlers();
LoadGridPlugins();
LoadPlugins();
m_httpServer.Start();
@ -116,16 +116,12 @@ namespace OpenSim.Grid.GridServer
m_httpServer.AddStreamHandler(new RestStreamHandler("POST", "/regions/", m_gridManager.RestSetRegionMethod));
}
protected void grid_plugin_initialiser_ (IPlugin plugin)
protected void LoadPlugins()
{
IGridPlugin p = plugin as IGridPlugin;
p.Initialise (this);
}
PluginLoader<IGridPlugin> loader =
new PluginLoader<IGridPlugin> (new GridPluginInitialiser (this));
protected void LoadGridPlugins()
{
PluginLoader<IGridPlugin> loader = new PluginLoader<IGridPlugin> (".");
loader.Load ("/OpenSim/GridServer", grid_plugin_initialiser_);
loader.Load ("/OpenSim/GridServer", ".");
m_plugins = loader.Plugins;
}
@ -181,7 +177,7 @@ namespace OpenSim.Grid.GridServer
public override void Shutdown()
{
foreach (IGridPlugin plugin in m_plugins) plugin.Close();
foreach (IGridPlugin plugin in m_plugins) plugin.Dispose();
base.Shutdown();
}

View File

@ -39,4 +39,15 @@ namespace OpenSim.Grid.GridServer
void Initialise(GridServerBase gridServer);
void Close();
}
public class GridPluginInitialiser : PluginInitialiserBase
{
private GridServerBase server;
public GridPluginInitialiser (GridServerBase s) { server = s; }
public override void Initialise (IPlugin plugin)
{
IGridPlugin p = plugin as IGridPlugin;
p.Initialise (server);
}
}
}

View File

@ -37,4 +37,15 @@ namespace OpenSim
{
void Initialise(OpenSimBase openSim);
}
public class ApplicationPluginInitialiser : PluginInitialiserBase
{
private OpenSimBase server;
public ApplicationPluginInitialiser (OpenSimBase s) { server = s; }
public override void Initialise (IPlugin plugin)
{
IApplicationPlugin p = plugin as IApplicationPlugin;
p.Initialise (server);
}
}
}

View File

@ -332,16 +332,12 @@ namespace OpenSim
m_networkServersInfo.loadFromConfiguration(m_config.Source);
}
protected void plugin_initialiser_ (IPlugin plugin)
{
IApplicationPlugin p = plugin as IApplicationPlugin;
p.Initialise (this);
}
protected void LoadPlugins()
{
PluginLoader<IApplicationPlugin> loader = new PluginLoader<IApplicationPlugin> (".");
loader.Load ("/OpenSim/Startup", plugin_initialiser_);
PluginLoader<IApplicationPlugin> loader =
new PluginLoader<IApplicationPlugin> (new ApplicationPluginInitialiser (this));
loader.Load ("/OpenSim/Startup", ".");
m_plugins = loader.Plugins;
}
@ -733,3 +729,4 @@ namespace OpenSim