|
using System;
using System.Collections;
using System.Xml;
using System.Reflection;
using System.Configuration;
namespace Params
{
public class ParamCollection
{
#region Internal Fields
internal string ShortControlString; // usually "/" or "-"
internal string LongControlString; //usually "--"
internal char[] AttribChars; // ' ' or '='
internal char SeparatorChar; // ' ' - the separator betweeb the values of the same parameter
internal bool AutoGenerateParams; // if unknown params are found, generate them and add them to the dictionary ?
internal bool DefaultAllowMultipleValues;
internal bool DefaultIsOptional;
internal ParamType DefaultType;
internal Hashtable hashtable;
#endregion
#region Dictionary Methods
public Param this[string name]
{
get
{
return (Param)hashtable[name];
}
}
public ICollection Names
{
get
{
return this.hashtable.Keys;
}
}
public bool Contains(string key)
{
return hashtable.Contains(key);
}
internal void Add(Param p)
{
if(p.ShortName != null && p.ShortName != string.Empty)
hashtable.Add(p.ShortName, p);
if(p.LongName != null && p.LongName != string.Empty)
hashtable.Add(p.LongName, p);
}
internal void Remove(string name)
{
Param p = (Param)hashtable[name];
Remove(p);
}
internal void Remove(Param p)
{
foreach(string s in hashtable.Keys)
{
if(p == hashtable[s])
hashtable.Remove(s);
}
}
#endregion
#region Constructor
internal ParamCollection()
{
this.hashtable = new Hashtable();
}
#endregion
#region Singleton Related
public static readonly ParamCollection ApplicationParameters;
static ParamCollection()
{
try
{
ApplicationParameters = (ParamCollection)ConfigurationSettings.GetConfig("parameters");
}
catch
{
Console.WriteLine("An error occured while reading the configuration file. Please fix it and run the program again.");
Environment.Exit(-1);
}
try
{
//TODO: Should optimize this, but it's only done once, no big performance hit here
System.Text.StringBuilder sbCmdLine = new System.Text.StringBuilder();
string []cmdargs = Environment.GetCommandLineArgs();
for(int i=1; i<cmdargs.Length; i++)
{
sbCmdLine.Append(cmdargs[i]);
sbCmdLine.Append(' ');
}
string cmdLine = sbCmdLine.ToString();
int index = 0;
while(index < cmdLine.Length && char.IsWhiteSpace(cmdLine[index]))
index++;
while(index < cmdLine.Length)
{
Param p = null;
//-1 is none -> no parameter found, 0 is short parameter, 1 is long parameter
int paramLength = Helper.BeginsWith(cmdLine, index, ApplicationParameters.LongControlString, ApplicationParameters.ShortControlString);
if(paramLength != -1)//a parameter is there
{
index += (paramLength == 1 ? ApplicationParameters.ShortControlString.Length : ApplicationParameters.LongControlString.Length);
int nameEndIndex = cmdLine.IndexOfAny(ApplicationParameters.AttribChars, index);
if(nameEndIndex == -1)
nameEndIndex = cmdLine.Length-1;
string name = cmdLine.Substring(index, nameEndIndex-index).Trim();
p = ApplicationParameters[name];
if(p == null)
{
if(ApplicationParameters.AutoGenerateParams)
{
p = new Param(name, null, ApplicationParameters);
ApplicationParameters.Add(p);
}
else
{
throw new ParameterException("Invalid parameter specified");
}
}
if((paramLength == 0 && p.LongName != name) || (paramLength == 1 && p.ShortName != name))
throw(new ParameterException("Cannot parse command line"));
index = nameEndIndex+1;
}
else
{
foreach(Param pd in ApplicationParameters.hashtable.Values)
{
if(pd.IsDefault)
{
p = pd;
break;
}
}
if(p == null)
{
if(ApplicationParameters.AutoGenerateParams)
{
p = new Param("_default_", null, true, true);
ApplicationParameters.Add(p);
}
else
{
throw new ParameterException("Invalid parameter specified");
}
}
}
//time to read the value of the parameter
int valueEndIndex = cmdLine.Length;
string strValue = string.Empty;
//trim all the white spaces and attrib chars
string attribString = new String(ApplicationParameters.AttribChars);
while(index < cmdLine.Length && (char.IsWhiteSpace(cmdLine[index]) || (attribString.IndexOf(cmdLine[index]) != -1)))
index++;
if(index < cmdLine.Length)
{
valueEndIndex = Helper.GetNextParamIndex(cmdLine, index, ApplicationParameters.ShortControlString, ApplicationParameters.LongControlString);
strValue = cmdLine.Substring(index, valueEndIndex - index).Trim();
}
//TODO: split strValue by separatorChar and add all the values
if(strValue == string.Empty)
{
if(p.DefaultValue != null)
{
strValue = p.DefaultValue.ToString();
}
else
{
while(valueEndIndex < cmdLine.Length && char.IsWhiteSpace(cmdLine[valueEndIndex]))
valueEndIndex++;
if(cmdLine.Substring(valueEndIndex, ApplicationParameters.LongControlString.Length) == ApplicationParameters.LongControlString)
valueEndIndex += ApplicationParameters.LongControlString.Length;
if(cmdLine.Substring(valueEndIndex, ApplicationParameters.ShortControlString.Length) == ApplicationParameters.ShortControlString)
valueEndIndex += ApplicationParameters.ShortControlString.Length;
valueEndIndex = Helper.GetNextParamIndex(cmdLine, valueEndIndex, ApplicationParameters.ShortControlString, ApplicationParameters.LongControlString);
strValue = cmdLine.Substring(index, valueEndIndex-index);
}
}
if(p.AllowMultipleValues)
p.AddValue(strValue);
else
p.SetValue(strValue);
index = valueEndIndex;
while(index < cmdLine.Length && char.IsWhiteSpace(cmdLine[index]))
index++;
}
ApplicationParameters.Validate();
}
catch//(Exception ex)
{
ApplicationParameters.PrintUsage();
Environment.Exit(-1);
}
}
#endregion
public string GetUsage()
{
System.Text.StringBuilder sb = new System.Text.StringBuilder(1024);
//TODO: Optimize this
ArrayList list = new ArrayList();
if(DefaultIsOptional)
sb.Append("All parameters are optional unless specified otherwise.\n");
else
sb.Append("All parameters are mandatory unless specified otherwise.\n");
foreach(Param p in hashtable.Values)
{
if(list.Contains(p))
continue;
else
list.Add(p);
sb.Append("\n");
if(p.ShortName != null)
{
sb.Append(ShortControlString);
sb.Append(p.ShortName);
}
if(p.LongName != null)
{
if(p.ShortName != null)
sb.Append(", ");
sb.Append(LongControlString);
sb.Append(p.LongName);
}
sb.Append("\t: ");
sb.Append("Type: ");
sb.Append(p.Type.ToString());
sb.Append(". ");
if(p.DefaultValue != null)
{
sb.Append("Default value: ");
sb.Append(p.DefaultValue.ToString());
sb.Append(". ");
}
if(p.IsOptional && !DefaultIsOptional)
sb.Append("This parameter is optional. ");
if(!p.IsOptional && DefaultIsOptional)
sb.Append("This parameter is mandatory. ");
if(p.Description != null)
{
sb.Append("Description: ");
sb.Append(p.Description);
sb.Append(" ");
}
//sb.Append("\n");
}
sb.Append("\n\n");
return sb.ToString();
}
public void PrintUsage()
{
System.Console.Write(GetUsage());
}
public bool Validate()
{
foreach(Param p in hashtable.Values)
{
if(!p.IsOptional && p.Value == null)
throw new ParameterException("Mandatory parameter not specified");
//TODO: A lot more checking to do.
}
return true;
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Just you average programmer geek from Romania. Student at Faculty of Computer Science, Al. I. Cuza University Iasi, Romania.