128 lines
3.2 KiB
C#
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;
|
|
}
|
|
}
|
|
} |