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

@ -61,4 +61,20 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
void Initialise(); 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> /// <summary>
/// Exception thrown if an incorrect number of plugins are loaded /// Exception thrown if an incorrect number of plugins are loaded
/// </summary> /// </summary>
public class PluginCountInvalidException : Exception public class PluginConstraintViolatedException : Exception
{ {
public PluginCountInvalidException () : base() {} public PluginConstraintViolatedException () : base() {}
public PluginCountInvalidException (string msg) : base(msg) {} public PluginConstraintViolatedException (string msg) : base(msg) {}
public PluginCountInvalidException (string msg, Exception e) : base(msg, e) {} 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> /// <summary>
@ -49,26 +59,42 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
public class PluginLoader <T> : IDisposable where T : IPlugin 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 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<T> loaded = new List<T>();
private List<string> extpoints = new List<string>(); 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 static readonly ILog log
private void default_initialiser_ (IPlugin p) { p.Initialise(); } = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public PluginLoader (string dir) public PluginInitialiserBase Initialiser
{ {
AddPluginDir (dir); set { initialiser = value; }
get { return initialiser; }
}
public List<T> Plugins
{
get { return loaded; }
}
public PluginLoader ()
{
Initialiser = new PluginInitialiserBase();
}
public PluginLoader (PluginInitialiserBase init)
{
Initialiser = init;
}
public PluginLoader (PluginInitialiserBase init, string dir)
{
Initialiser = init;
AddPluginDir (dir);
} }
public void AddPluginDir (string dir) public void AddPluginDir (string dir)
@ -84,65 +110,45 @@ namespace OpenSim.Framework
extpoints.Add (extpoint); 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)); constraints.Add (extpoint, cons);
}
public void Load (string extpoint, string dir)
{
AddPluginDir (dir);
AddExtensionPoint (extpoint); AddExtensionPoint (extpoint);
Load();
} }
public void LoadAll (Initialiser initialise) public void Load ()
{
foreach (string pt in extpoints)
Load (pt, initialise);
}
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)
{ {
suppress_console_output_ (true); suppress_console_output_ (true);
AddinManager.Registry.Update (null); AddinManager.Registry.Update (null);
suppress_console_output_ (false); suppress_console_output_ (false);
ExtensionNodeList ns = AddinManager.GetExtensionNodes(extpoint); foreach (string ext in extpoints)
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)
{ {
T p = (T) n.CreateInstance(); if (constraints.ContainsKey (ext))
initialise (p); {
Plugins.Add (p); 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 () public void Dispose ()
{ {
foreach (T p in Plugins) foreach (T p in Plugins)
@ -174,6 +180,73 @@ namespace OpenSim.Framework
System.Console.SetOut(prev_console_); 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(); AddHttpHandlers();
LoadGridPlugins(); LoadPlugins();
m_httpServer.Start(); m_httpServer.Start();
@ -116,16 +116,12 @@ namespace OpenSim.Grid.GridServer
m_httpServer.AddStreamHandler(new RestStreamHandler("POST", "/regions/", m_gridManager.RestSetRegionMethod)); 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; PluginLoader<IGridPlugin> loader =
p.Initialise (this); new PluginLoader<IGridPlugin> (new GridPluginInitialiser (this));
}
protected void LoadGridPlugins() loader.Load ("/OpenSim/GridServer", ".");
{
PluginLoader<IGridPlugin> loader = new PluginLoader<IGridPlugin> (".");
loader.Load ("/OpenSim/GridServer", grid_plugin_initialiser_);
m_plugins = loader.Plugins; m_plugins = loader.Plugins;
} }
@ -181,7 +177,7 @@ namespace OpenSim.Grid.GridServer
public override void Shutdown() public override void Shutdown()
{ {
foreach (IGridPlugin plugin in m_plugins) plugin.Close(); foreach (IGridPlugin plugin in m_plugins) plugin.Dispose();
base.Shutdown(); base.Shutdown();
} }

View File

@ -39,4 +39,15 @@ namespace OpenSim.Grid.GridServer
void Initialise(GridServerBase gridServer); void Initialise(GridServerBase gridServer);
void Close(); 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); 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); m_networkServersInfo.loadFromConfiguration(m_config.Source);
} }
protected void plugin_initialiser_ (IPlugin plugin)
{
IApplicationPlugin p = plugin as IApplicationPlugin;
p.Initialise (this);
}
protected void LoadPlugins() protected void LoadPlugins()
{ {
PluginLoader<IApplicationPlugin> loader = new PluginLoader<IApplicationPlugin> ("."); PluginLoader<IApplicationPlugin> loader =
loader.Load ("/OpenSim/Startup", plugin_initialiser_); new PluginLoader<IApplicationPlugin> (new ApplicationPluginInitialiser (this));
loader.Load ("/OpenSim/Startup", ".");
m_plugins = loader.Plugins; m_plugins = loader.Plugins;
} }
@ -733,3 +729,4 @@ namespace OpenSim