asternet/Asterisk.2013/Asterisk.NET/FastAGI/MappingStrategies/ResourceMappingStrategy.cs
2014-01-08 14:16:39 +00:00

128 lines
3.2 KiB
C#

using System;
using System.Collections;
using System.Resources;
using System.Reflection;
namespace AsterNET.FastAGI.MappingStrategies
{
/// <summary>
/// A MappingStrategy that is configured via a resource bundle.<br/>
/// The resource bundle contains the script part of the url as key and the fully
/// qualified class name of the corresponding AGIScript as value.<br/>
/// Example:
/// <pre>
/// noopcommand = AsterNET.FastAGI.Command.NoopCommand
/// </pre>
/// NoopCommand must implement the AGIScript interface and have a default constructor with no parameters.<br/>
/// </summary>
public class ResourceMappingStrategy : IMappingStrategy
{
#if LOGGER
private Logger logger = Logger.Instance();
#endif
private string resourceName;
private Hashtable mapping;
public ResourceMappingStrategy()
{
this.resourceName = Common.AGI_DEFAULT_RESOURCE_BUNDLE_NAME;
this.mapping = null;
}
public ResourceMappingStrategy(string resourceName)
{
this.resourceName = resourceName;
this.mapping = null;
}
public AGIScript DetermineScript(AGIRequest request)
{
AGIScript script = null;
if (mapping != null)
lock (mapping.SyncRoot)
{
if (mapping.Contains(request.Script))
script = (AGIScript)mapping[request.Script];
}
return script;
}
public string ResourceBundleName
{
set
{
if (value == null)
{
mapping = null;
resourceName = null;
}
else if (this.resourceName != value)
{
this.resourceName = value;
Load();
}
}
}
public void Load()
{
string scriptName;
string className;
AGIScript agiScript;
if (mapping == null)
mapping = new Hashtable();
lock (mapping)
{
mapping.Clear();
try
{
ResourceReader rr = new ResourceReader(AppDomain.CurrentDomain.BaseDirectory + resourceName);
foreach (DictionaryEntry de in rr)
{
scriptName = (string)de.Key;
className = (string)de.Value;
agiScript = CreateAGIScriptInstance(className);
if(mapping.Contains(scriptName))
throw new AGIException(String.Format("Duplicate mapping name '{0}' in file {1}", scriptName, resourceName));
mapping.Add(scriptName, agiScript);
#if LOGGER
logger.Info("Added mapping for '" + scriptName + "' to class " + agiScript.GetType().FullName);
#endif
}
}
catch (Exception ex)
{
#if LOGGER
logger.Error("Resource bundle '" + resourceName + "' is missing.");
#endif
throw ex;
}
}
}
private AGIScript CreateAGIScriptInstance(string className)
{
Type agiScriptClass;
ConstructorInfo constructor;
AGIScript agiScript;
try
{
agiScriptClass = Type.GetType(className);
constructor = agiScriptClass.GetConstructor(new Type[]{});
agiScript = (AGIScript) constructor.Invoke(new object[]{});
}
catch(Exception ex)
{
#if LOGGER
logger.Error("Unable to create AGIScript instance of type " + className, ex);
return null;
#else
throw new AGIException("Unable to create AGIScript instance of type " + className, ex);
#endif
}
return agiScript;
}
}
}