using System;
using System.Collections;
using System.IO;
using System.Text;
namespace Commons.Collections{
/// <summary> This class extends normal Java properties by adding the possibility
/// to use the same key many times concatenating the value strings
/// instead of overwriting them.
///
/// <p>The Extended Properties syntax is explained here:
///
/// <ul>
/// <li>
/// Each property has the syntax <code>key = value</code>
/// </li>
/// <li>
/// The <i>key</i> may use any character but the equal sign '='.
/// </li>
/// <li>
/// <i>value</i> may be separated on different lines if a backslash
/// is placed at the end of the line that continues below.
/// </li>
/// <li>
/// If <i>value</i> is a list of strings, each token is separated
/// by a comma ','.
/// </li>
/// <li>
/// Commas in each token are escaped placing a backslash right before
/// the comma.
/// </li>
/// <li>
/// If a <i>key</i> is used more than once, the values are appended
/// like if they were on the same line separated with commas.
/// </li>
/// <li>
/// Blank lines and lines starting with character '#' are skipped.
/// </li>
/// <li>
/// If a property is named "include" (or whatever is defined by
/// setInclude() and getInclude() and the value of that property is
/// the full path to a file on disk, that file will be included into
/// the ConfigurationsRepository. You can also pull in files relative
/// to the parent configuration file. So if you have something
/// like the following:
///
/// include = additional.properties
///
/// Then "additional.properties" is expected to be in the same
/// directory as the parent configuration file.
///
/// Duplicate name values will be replaced, so be careful.
///
/// </li>
/// </ul>
///
/// <p>Here is an example of a valid extended properties file:
///
/// <p><pre>
/// # lines starting with # are comments
///
/// # This is the simplest property
/// key = value
///
/// # A long property may be separated on multiple lines
/// longvalue = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
/// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
///
/// # This is a property with many tokens
/// tokens_on_a_line = first token, second token
///
/// # This sequence generates exactly the same result
/// tokens_on_multiple_lines = first token
/// tokens_on_multiple_lines = second token
///
/// # commas may be escaped in tokens
/// commas.excaped = Hi\, what'up?
/// </pre>
///
/// <p><b>NOTE</b>: this class has <b>not</b> been written for
/// performance nor low memory usage. In fact, it's way slower than it
/// could be and generates too much memory garbage. But since
/// performance is not an issue during intialization (and there is not
/// much time to improve it), I wrote it this way. If you don't like
/// it, go ahead and tune it up!
/// </summary>
public class ExtendedProperties : Hashtable {
private static readonly Byte DEFAULT_BYTE = 0;
private static readonly Boolean DEFAULT_BOOLEAN = false;
private static readonly Int16 DEFAULT_INT16 = 0;
private static readonly Int32 DEFAULT_INT32 = 0;
private static readonly Single DEFAULT_SINGLE = 0;
private static readonly Int64 DEFAULT_INT64 = 0;
private static readonly Double DEFAULT_DOUBLE = 0;
/// <summary> Default configurations repository.
/// </summary>
private ExtendedProperties defaults;
/// <summary> The file connected to this repository (holding comments and
/// such).
/// *
/// @serial
/// </summary>
protected internal String file;
/// <summary> Base path of the configuration file used to create
/// this ExtendedProperties object.
/// </summary>
protected internal String basePath;
/// <summary> File separator.
/// </summary>
protected internal String fileSeparator = "\\";
/// <summary> Has this configuration been intialized.
/// </summary>
protected internal bool isInitialized = false;
/// <summary> This is the name of the property that can point to other
/// properties file for including other properties files.
/// </summary>
protected internal static String include = "include";
/// <summary> These are the keys in the order they listed
/// in the configuration file. This is useful when
/// you wish to perform operations with configuration
/// information in a particular order.
/// </summary>
protected internal ArrayList keysAsListed = new ArrayList();
/// <summary> Creates an empty extended properties object.
/// </summary>
public ExtendedProperties():base() {}
/// <summary> Creates and loads the extended properties from the specified
/// file.
/// *
/// </summary>
/// <param name="file">A String.
/// </param>
/// <exception cref="">IOException.
///
/// </exception>
public ExtendedProperties(String file):this(file, null) {}
/// <summary> Creates and loads the extended properties from the specified
/// file.
/// *
/// </summary>
/// <param name="file">A String.
/// </param>
/// <exception cref="">IOException.
///
/// </exception>
public ExtendedProperties(String file, String defaultFile) {
this.file = file;
basePath = new FileInfo(file).FullName;
basePath = basePath.Substring(0, (basePath.LastIndexOf(fileSeparator) + 1) - (0));
this.Load(new FileStream(file, FileMode.Open, FileAccess.Read));
if (defaultFile != null) {
defaults = new ExtendedProperties(defaultFile);
}
}
/// <summary> Private initializer method that sets up the generic
/// resources.
/// *
/// </summary>
/// <exception cref="">IOException, if there was an I/O problem.
///
/// </exception>
private void Init(ExtendedProperties exp) {
isInitialized = true;
}
/// <summary> Indicate to client code whether property
/// resources have been initialized or not.
/// </summary>
public virtual bool IsInitialized() {
return isInitialized;
}
public virtual String Include {
get { return ExtendedProperties.include; }
set { ExtendedProperties.include = value; }
}
public virtual IEnumerator Keys {
get { return keysAsListed.GetEnumerator(); }
}
/// <summary> Gets the property value for including other properties files.
/// By default it is "include".
/// *
/// </summary>
/// <returns>A String.
///
/// </returns>
/// <summary> Sets the property value for including other properties files.
/// By default it is "include".
/// *
/// </summary>
/// <param name="inc">A String.
///
/// </param>
/// <summary> Load the properties from the given input stream.
/// *
/// </summary>
/// <param name="input">An InputStream.
/// </param>
/// <exception cref="">IOException.
///
/// </exception>
public virtual void Load(Stream input) {
Load(input, null);
}
/// <summary> Load the properties from the given input stream
/// and using the specified encoding.
/// *
/// </summary>
/// <param name="input">An InputStream.
/// </param>
/// <param name="enc">An encoding.
/// </param>
/// <exception cref="">IOException.
///
/// </exception>
//UPGRADE_NOTE: Synchronized keyword was removed from method 'load'. Lock expression was added. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1027"'
public virtual void Load(Stream input, String enc) {
lock(this) {
PropertiesReader reader = null;
if (enc != null) {
try {
reader = new PropertiesReader(new StreamReader(input, Encoding.GetEncoding(enc)));
} catch (IOException e) {
// Get one with the default encoding...
}
}
if (reader == null) {
reader = new PropertiesReader(new StreamReader(input));
}
try {
while (true) {
String line = reader.ReadProperty();
int equalSign = line.IndexOf((Char) '=');
if (equalSign > 0) {
String key = line.Substring(0, (equalSign) - (0)).Trim();
String value_Renamed = line.Substring(equalSign + 1).Trim();
/*
* Configure produces lines like this ... just
* ignore them.
*/
if (String.Empty.Equals(value_Renamed))
continue;
if (Include != null && key.ToUpper().Equals(Include.ToUpper())) {
/*
* Recursively load properties files.
*/
FileInfo file = null;
if (value_Renamed.StartsWith(fileSeparator)) {
/*
* We have an absolute path so we'll
* use this.
*/
file = new FileInfo(value_Renamed);
} else {
/*
* We have a relative path, and we have
* two possible forms here. If we have the
* "./" form then just strip that off first
* before continuing.
*/
if (value_Renamed.StartsWith("." + fileSeparator)) {
value_Renamed = value_Renamed.Substring(2);
}
file = new FileInfo(basePath + value_Renamed);
}
bool tmpBool;
if (File.Exists(file.FullName)) {
tmpBool = true;
} else {
tmpBool = Directory.Exists(file.FullName);
}
// TODO: make sure file is readable or handle exception appropriately
//if (file != null && tmpBool && file.canRead()) {
if (file != null && tmpBool) {
Load(new FileStream(file.FullName, FileMode.Open, FileAccess.Read));
}
} else {
AddProperty(key, value_Renamed);
}
}
}
} catch (NullReferenceException e) {
/*
* Should happen only when EOF is reached.
*/
return ;
}
reader.Close();
}
}
/// <summary> Gets a property from the configuration.
/// *
/// </summary>
/// <param name="key">property to retrieve
/// </param>
/// <returns>value as object. Will return user value if exists,
/// if not then default value if exists, otherwise null
///
/// </returns>
public virtual Object GetProperty(String key) {
/*
* first, try to get from the 'user value' store
*/
Object o = this[key];
if (o == null) {
/*
* if there isn't a value there, get it from the
* defaults if we have them
*/
if (defaults != null) {
o = defaults[key];
}
}
return o;
}
/// <summary> Add a property to the configuration. If it already
/// exists then the value stated here will be added
/// to the configuration entry. For example, if
/// *
/// resource.loader = file
/// *
/// is already present in the configuration and you
/// *
/// addProperty("resource.loader", "classpath")
/// *
/// Then you will end up with a Vector like the
/// following:
/// *
/// ["file", "classpath"]
/// *
/// </summary>
/// <param name="String">key
/// </param>
/// <param name="String">value
///
/// </param>
public virtual void AddProperty(String key, Object token) {
Object o = this[key];
/*
* $$$ GMJ
* FIXME : post 1.0 release, we need to not assume
* that a scalar is a String - it can be an Object
* so we should make a little vector-like class
* say, Foo that wraps (not extends Vector),
* so we can do things like
* if ( !( o instanceof Foo) )
* so we know it's our 'vector' container
*
* This applies throughout
*/
if (o is String) {
ArrayList v = new ArrayList(2);
v.Add(o);
v.Add(token);
CollectionsUtil.PutElement(this, key, v);
} else if (o is ArrayList) {
((ArrayList) o).Add(token);
} else {
/*
* This is the first time that we have seen
* request to place an object in the
* configuration with the key 'key'. So
* we just want to place it directly into
* the configuration ... but we are going to
* make a special exception for String objects
* that contain "," characters. We will take
* CSV lists and turn the list into a vector of
* Strings before placing it in the configuration.
* This is a concession for Properties and the
* like that cannot parse multiple same key
* values.
*/
if (token is String && ((String) token).IndexOf(PropertiesTokenizer.DELIMITER) > 0) {
PropertiesTokenizer tokenizer = new PropertiesTokenizer((String) token);
while (tokenizer.HasMoreTokens()) {
String s = tokenizer.NextToken();
/*
* we know this is a string, so make sure it
* just goes in rather than risking vectorization
* if it contains an escaped comma
*/
AddStringProperty(key, s);
}
} else {
/*
* We want to keep track of the order the keys
* are parsed, or dynamically entered into
* the configuration. So when we see a key
* for the first time we will place it in
* an ArrayList so that if a client class needs
* to perform operations with configuration
* in a definite order it will be possible.
*/
AddPropertyDirect(key, token);
}
}
}
/// <summary> Adds a key/value pair to the map. This routine does
/// no magic morphing. It ensures the keylist is maintained
/// *
/// </summary>
/// <param name="key">key to use for mapping
/// </param>
/// <param name="obj">object to store
///
/// </param>
private void AddPropertyDirect(String key, Object obj) {
/*
* safety check
*/
if (!ContainsKey(key)) {
keysAsListed.Add(key);
}
/*
* and the value
*/
CollectionsUtil.PutElement(this, key, obj);
}
/// <summary> Sets a string property w/o checking for commas - used
/// internally when a property has been broken up into
/// strings that could contain escaped commas to prevent
/// the inadvertant vectorization.
///
/// Thanks to Leon Messerschmidt for this one.
///
/// </summary>
private void AddStringProperty(String key, String token) {
Object o = this[key];
/*
* $$$ GMJ
* FIXME : post 1.0 release, we need to not assume
* that a scalar is a String - it can be an Object
* so we should make a little vector-like class
* say, Foo that wraps (not extends Vector),
* so we can do things like
* if ( !( o instanceof Foo) )
* so we know it's our 'vector' container
*
* This applies throughout
*/
/*
* do the usual thing - if we have a value and
* it's scalar, make a vector, otherwise add
* to the vector
*/
if (o is String) {
ArrayList v = new ArrayList(2);
v.Add(o);
v.Add(token);
CollectionsUtil.PutElement(this, key, v);
} else if (o is ArrayList) {
((ArrayList) o).Add(token);
} else {
AddPropertyDirect(key, token);
}
}
/// <summary> Set a property, this will replace any previously
/// set values. Set values is implicitly a call
/// to clearProperty(key), addProperty(key,value).
/// </summary>
/// <param name="String">key
/// </param>
/// <param name="String">value
/// </param>
public virtual void SetProperty(String key, Object value_Renamed) {
ClearProperty(key);
AddProperty(key, value_Renamed);
}
/// <summary> Save the properties to the given outputstream.
/// </summary>
/// <param name="output">An OutputStream.
/// </param>
/// <param name="header">A String.
/// </param>
/// <exception cref="">IOException.
/// </exception>
public virtual void Save(TextWriter output, String Header) {
lock(this) {
if (output != null) {
//TODO - why did they do this?
//StreamWriter theWrtr = new StreamWriter(output);
TextWriter theWrtr = output;
if (Header != null) {
theWrtr.WriteLine(Header);
}
IEnumerator theKeys = (IEnumerator) Keys;
//UPGRADE_TODO: method 'java.util.Enumeration.hasMoreElements' was converted to ' ' which has a different behavior. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1073_javautilEnumerationhasMoreElements"'
while (theKeys.MoveNext()) {
//UPGRADE_TODO: method 'java.util.Enumeration.nextElement' was converted to ' ' which has a different behavior. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1073_javautilEnumerationnextElement"'
String key = (String) theKeys.Current;
Object value_Renamed = this[(Object) key];
if (value_Renamed != null) {
if (value_Renamed is String) {
StringBuilder currentOutput = new StringBuilder();
currentOutput.Append(key);
currentOutput.Append("=");
currentOutput.Append((String) value_Renamed);
theWrtr.WriteLine(currentOutput.ToString());
} else if (value_Renamed is ArrayList) {
ArrayList values = (ArrayList) value_Renamed;
IEnumerator valuesEnum = values.GetEnumerator();
//UPGRADE_TODO: method 'java.util.Enumeration.hasMoreElements' was converted to ' ' which has a different behavior. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1073_javautilEnumerationhasMoreElements"'
while (valuesEnum.MoveNext()) {
//UPGRADE_TODO: method 'java.util.Enumeration.nextElement' was converted to ' ' which has a different behavior. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1073_javautilEnumerationnextElement"'
String currentElement = (String) valuesEnum.Current;
StringBuilder currentOutput = new StringBuilder();
currentOutput.Append(key);
currentOutput.Append("=");
currentOutput.Append(currentElement);
theWrtr.WriteLine(currentOutput.ToString());
}
}
}
theWrtr.WriteLine();
theWrtr.Flush();
}
}
}
}
/// <summary> Combines an existing Hashtable with this Hashtable.
/// *
/// Warning: It will overwrite previous entries without warning.
/// *
/// </summary>
/// <param name="">ExtendedProperties
///
/// </param>
public virtual void Combine(ExtendedProperties c) {
IEnumerator i = c.Keys;
while (i.MoveNext()) {
String key = i.Current.ToString();
SetProperty(key, c[key]);
}
}
/// <summary> Clear a property in the configuration.
/// *
/// </summary>
/// <param name="String">key to remove along with corresponding value.
///
/// </param>
public virtual void ClearProperty(String key) {
if (ContainsKey(key)) {
/*
* we also need to rebuild the keysAsListed or else
* things get *very* confusing
*/
for (int i = 0; i < keysAsListed.Count; i++) {
if (((String) keysAsListed[i]).Equals(key)) {
keysAsListed.RemoveAt(i);
break;
}
}
Remove(key);
}
}
/// <summary> Get the list of the keys contained in the configuration
/// repository.
/// *
/// </summary>
/// <returns>An Iterator.
///
/// </returns>
/// <summary> Get the list of the keys contained in the configuration
/// repository that match the specified prefix.
/// *
/// </summary>
/// <param name="prefix">The prefix to test against.
/// </param>
/// <returns>An Iterator of keys that match the prefix.
///
/// </returns>
public virtual IEnumerator GetKeys(String prefix) {
IEnumerator keys = Keys;
ArrayList matchingKeys = new ArrayList();
while (keys.MoveNext()) {
Object key = keys.Current;
if (key is String && ((String) key).StartsWith(prefix)) {
matchingKeys.Add(key);
}
}
return matchingKeys.GetEnumerator();
}
/// <summary> Create an ExtendedProperties object that is a subset
/// of this one. Take into account duplicate keys
/// by using the setProperty() in ExtendedProperties.
/// *
/// </summary>
/// <param name="String">prefix
///
/// </param>
public virtual ExtendedProperties Subset(String prefix) {
ExtendedProperties c = new ExtendedProperties();
IEnumerator keys = Keys;
bool validSubset = false;
while (keys.MoveNext()) {
Object key = keys.Current;
if (key is String && ((String) key).StartsWith(prefix)) {
if (!validSubset) {
validSubset = true;
}
String newKey = null;
/*
* Check to make sure that c.subset(prefix) doesn't
* blow up when there is only a single property
* with the key prefix. This is not a useful
* subset but it is a valid subset.
*/
if (((String) key).Length == prefix.Length) {
newKey = prefix;
} else {
newKey = ((String) key).Substring(prefix.Length + 1);
}
/*
* use addPropertyDirect() - this will plug the data as
* is into the Map, but will also do the right thing
* re key accounting
*/
c.AddPropertyDirect(newKey, this[key]);
}
}
if (validSubset) {
return c;
} else {
return null;
}
}
/// <summary> Display the configuration for debugging
/// purposes.
/// </summary>
public override String ToString() {
StringBuilder sb = new StringBuilder();
IEnumerator i = Keys;
i.Reset();
while (i.MoveNext()) {
String key = (String) i.Current;
Object value = this[key];
sb.Append(key + " => " + ValueToString(value)).Append(Environment.NewLine);
}
return sb.ToString();
}
private String ValueToString(Object value) {
if (value is ArrayList) {
String s = "ArrayList :: ";
foreach(Object o in (ArrayList)value) {
if (!s.EndsWith(", ")) {
s += ", ";
}
s += "[" + o.ToString() + "]";
}
return s;
} else {
return value.ToString();
}
}
/// <summary> Get a string associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <returns>The associated string.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a String.
///
/// </exception>
public virtual String GetString(String key) {
return GetString(key, null);
}
/// <summary> Get a string associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <param name="defaultValue">The default value.
/// </param>
/// <returns>The associated string if key is found,
/// default value otherwise.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a String.
///
/// </exception>
public virtual String GetString(String key, String defaultValue) {
Object value_Renamed = this[key];
if (value_Renamed is String) {
return (String) value_Renamed;
} else if (value_Renamed == null) {
if (defaults != null) {
return defaults.GetString(key, defaultValue);
} else {
return defaultValue;
}
} else if (value_Renamed is ArrayList) {
//UPGRADE_TODO: Method java.util.Vector.get was not converted. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1095"'
return (String) ((ArrayList) value_Renamed)[0];
} else {
throw new InvalidCastException('\'' + key + "' doesn't map to a String object");
}
}
/// <summary> Get a list of properties associated with the given
/// configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <returns>The associated properties if key is found.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a String/Vector.
/// </exception>
/// <exception cref="">IllegalArgumentException if one of the tokens is
/// malformed (does not contain an equals sign).
///
/// </exception>
public virtual Hashtable GetProperties(String key) {
//UPGRADE_TODO: Format of property file may need to be changed. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1089"'
return GetProperties(key, new Hashtable());
}
/// <summary> Get a list of properties associated with the given
/// configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <returns>The associated properties if key is found.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a String/Vector.
/// </exception>
/// <exception cref="">IllegalArgumentException if one of the tokens is
/// malformed (does not contain an equals sign).
///
/// </exception>
// NOTE: java use java.util.Properties - the conversion used Configuration.AppSettingsReader - i am going to convert to hashtable
public virtual Hashtable GetProperties(String key, Hashtable defaults) {
/*
* Grab an array of the tokens for this key.
*/
String[] tokens = GetStringArray(key);
/*
* Each token is of the form 'key=value'.
*/
//UPGRADE_TODO: Format of property file may need to be changed. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1089"'
Hashtable props = new Hashtable(defaults);
for (int i = 0; i < tokens.Length; i++) {
String token = tokens[i];
int equalSign = token.IndexOf((Char) '=');
if (equalSign > 0) {
String pkey = token.Substring(0, (equalSign) - (0)).Trim();
String pvalue = token.Substring(equalSign + 1).Trim();
CollectionsUtil.PutElement(props, pkey, pvalue);
} else {
throw new ArgumentException('\'' + token + "' does not contain " + "an equals sign");
}
}
return props;
}
/// <summary> Get an array of strings associated with the given configuration
/// key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <returns>The associated string array if key is found.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a String/Vector.
///
/// </exception>
public virtual String[] GetStringArray(String key) {
Object value_Renamed = this[key];
// What's your vector, Victor?
ArrayList vector;
if (value_Renamed is String) {
vector = new ArrayList(1);
vector.Add(value_Renamed);
} else if (value_Renamed is ArrayList) {
vector = (ArrayList) value_Renamed;
} else if (value_Renamed == null) {
if (defaults != null) {
return defaults.GetStringArray(key);
} else {
return new String[0];
}
} else {
throw new InvalidCastException('\'' + key + "' doesn't map to a String/Vector object");
}
String[] tokens = new String[vector.Count];
for (int i = 0; i < tokens.Length; i++) {
tokens[i] = (String) vector[i];
}
return tokens;
}
/// <summary> Get a Vector of strings associated with the given configuration
/// key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <returns>The associated Vector.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Vector.
///
/// </exception>
public virtual ArrayList GetVector(String key) {
return GetVector(key, null);
}
/// <summary> Get a Vector of strings associated with the given configuration
/// key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <param name="defaultValue">The default value.
/// </param>
/// <returns>The associated Vector.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Vector.
///
/// </exception>
public virtual ArrayList GetVector(String key, ArrayList defaultValue) {
Object value_Renamed = this[key];
if (value_Renamed is ArrayList) {
return (ArrayList) value_Renamed;
} else if (value_Renamed is String) {
ArrayList v = new ArrayList(1);
v.Add((String) value_Renamed);
CollectionsUtil.PutElement(this, key, v);
return v;
} else if (value_Renamed == null) {
if (defaults != null) {
return defaults.GetVector(key, defaultValue);
} else {
return ((defaultValue == null) ? new ArrayList() : defaultValue);
}
} else {
throw new InvalidCastException('\'' + key + "' doesn't map to a Vector object");
}
}
/// <summary> Get a boolean associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <returns>The associated boolean.
/// </returns>
/// <exception cref="">NoSuchElementException is thrown if the key doesn't
/// map to an existing object.
/// </exception>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Boolean.
///
/// </exception>
public virtual bool GetBoolean(String key) {
Boolean b = GetBoolean(key, DEFAULT_BOOLEAN);
if ((Object) b != null) {
return b;
} else {
throw new Exception('\'' + key + "' doesn't map to an existing object");
}
}
/// <summary> Get a boolean associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <param name="defaultValue">The default value.
/// </param>
/// <returns>The associated boolean if key is found and has valid
/// format, default value otherwise.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Boolean.
///
/// </exception>
public virtual Boolean GetBoolean(String key, Boolean defaultValue) {
Object value_Renamed = this[key];
if (value_Renamed is Boolean) {
return (Boolean) value_Renamed;
} else if (value_Renamed is String) {
String s = TestBoolean((String) value_Renamed);
Boolean b = s.ToUpper().Equals("TRUE");
CollectionsUtil.PutElement(this, key, b);
return b;
} else if (value_Renamed == null) {
if (defaults != null) {
return defaults.GetBoolean(key, defaultValue);
} else {
return defaultValue;
}
} else {
throw new InvalidCastException('\'' + key + "' doesn't map to a Boolean object");
}
}
/// <summary> Test whether the string represent by value maps to a boolean
/// value or not. We will allow <code>true</code>, <code>on</code>,
/// and <code>yes</code> for a <code>true</code> boolean value, and
/// <code>false</code>, <code>off</code>, and <code>no</code> for
/// <code>false</code> boolean values. Case of value to test for
/// boolean status is ignored.
/// *
/// </summary>
/// <param name="String">The value to test for boolean state.
/// </param>
/// <returns><code>true</code> or <code>false</code> if the supplied
/// text maps to a boolean value, or <code>null</code> otherwise.
///
/// </returns>
public virtual String TestBoolean(String value_Renamed) {
String s = ((String) value_Renamed).ToLower();
if (s.Equals("true") || s.Equals("on") || s.Equals("yes")) {
return "true";
} else if (s.Equals("false") || s.Equals("off") || s.Equals("no")) {
return "false";
} else {
return null;
}
}
/// <summary> Get a byte associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <returns>The associated byte.
/// </returns>
/// <exception cref="">NoSuchElementException is thrown if the key doesn't
/// map to an existing object.
/// </exception>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Byte.
/// </exception>
/// <exception cref="">NumberFormatException is thrown if the value mapped
/// by the key has not a valid number format.
///
/// </exception>
public virtual sbyte GetByte(String key) {
if (ContainsKey(key)) {
Byte b = GetByte(key, DEFAULT_BYTE);
return (sbyte) b;
} else {
throw new Exception('\'' + key + " doesn't map to an existing object");
}
}
/// <summary> Get a byte associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <param name="defaultValue">The default value.
/// </param>
/// <returns>The associated byte.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Byte.
/// </exception>
/// <exception cref="">NumberFormatException is thrown if the value mapped
/// by the key has not a valid number format.
///
/// </exception>
public virtual sbyte GetByte(String key, sbyte defaultValue) {
return (sbyte) GetByte(key, defaultValue);
}
/// <summary> Get a byte associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <param name="defaultValue">The default value.
/// </param>
/// <returns>The associated byte if key is found and has valid
/// format, default value otherwise.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Byte.
/// </exception>
/// <exception cref="">NumberFormatException is thrown if the value mapped
/// by the key has not a valid number format.
///
/// </exception>
public virtual Byte GetByte(String key, Byte defaultValue) {
Object value_Renamed = this[key];
if (value_Renamed is Byte) {
return (Byte) value_Renamed;
} else if (value_Renamed is String) {
Byte b = Byte.Parse((String) value_Renamed);
CollectionsUtil.PutElement(this, key, b);
return b;
} else if (value_Renamed == null) {
if (defaults != null) {
return defaults.GetByte(key, defaultValue);
} else {
return defaultValue;
}
} else {
throw new InvalidCastException('\'' + key + "' doesn't map to a Byte object");
}
}
/// <summary> Get a short associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <returns>The associated short.
/// </returns>
/// <exception cref="">NoSuchElementException is thrown if the key doesn't
/// map to an existing object.
/// </exception>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Short.
/// </exception>
/// <exception cref="">NumberFormatException is thrown if the value mapped
/// by the key has not a valid number format.
///
/// </exception>
public virtual short GetShort(String key) {
Int16 s = GetShort(key, DEFAULT_INT16);
if ((Object) s != null) {
return (short) s;
} else {
throw new Exception('\'' + key + "' doesn't map to an existing object");
}
}
/// <summary> Get a short associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <param name="defaultValue">The default value.
/// </param>
/// <returns>The associated short if key is found and has valid
/// format, default value otherwise.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Short.
/// </exception>
/// <exception cref="">NumberFormatException is thrown if the value mapped
/// by the key has not a valid number format.
///
/// </exception>
public virtual Int16 GetShort(String key, Int16 defaultValue) {
Object value_Renamed = this[key];
if (value_Renamed is Int16) {
return (Int16) value_Renamed;
} else if (value_Renamed is String) {
Int16 s = Int16.Parse((String) value_Renamed);
CollectionsUtil.PutElement(this, key, s);
return s;
} else if (value_Renamed == null) {
if (defaults != null) {
return defaults.GetShort(key, defaultValue);
} else {
return defaultValue;
}
} else {
throw new InvalidCastException('\'' + key + "' doesn't map to a Short object");
}
}
/// <summary> The purpose of this method is to get the configuration resource
/// with the given name as an integer.
/// *
/// </summary>
/// <param name="name">The resource name.
/// </param>
/// <returns>The value of the resource as an integer.
///
/// </returns>
public virtual int GetInt(String name) {
return GetInteger(name);
}
/// <summary> The purpose of this method is to get the configuration resource
/// with the given name as an integer, or a default value.
/// *
/// </summary>
/// <param name="name">The resource name
/// </param>
/// <param name="def">The default value of the resource.
/// </param>
/// <returns>The value of the resource as an integer.
///
/// </returns>
public virtual int GetInt(String name, int def) {
return GetInteger(name, def);
}
/// <summary> Get a int associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <returns>The associated int.
/// </returns>
/// <exception cref="">NoSuchElementException is thrown if the key doesn't
/// map to an existing object.
/// </exception>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Integer.
/// </exception>
/// <exception cref="">NumberFormatException is thrown if the value mapped
/// by the key has not a valid number format.
///
/// </exception>
public virtual int GetInteger(String key) {
Int32 i = GetInteger(key, DEFAULT_INT32);
if ((Object) i != null) {
return i;
} else {
throw new Exception('\'' + key + "' doesn't map to an existing object");
}
}
/// <summary> Get a int associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <param name="defaultValue">The default value.
/// </param>
/// <returns>The associated int if key is found and has valid
/// format, default value otherwise.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Integer.
/// </exception>
/// <exception cref="">NumberFormatException is thrown if the value mapped
/// by the key has not a valid number format.
///
/// </exception>
public virtual Int32 GetInteger(String key, Int32 defaultValue) {
Object value_Renamed = this[key];
if (value_Renamed is Int32) {
return (Int32) value_Renamed;
} else if (value_Renamed is String) {
Int32 i = Int32.Parse((String) value_Renamed);
CollectionsUtil.PutElement(this, key, i);
return i;
} else if (value_Renamed == null) {
if (defaults != null) {
return defaults.GetInteger(key, defaultValue);
} else {
return defaultValue;
}
} else {
throw new InvalidCastException('\'' + key + "' doesn't map to a Integer object");
}
}
/// <summary> Get a long associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <returns>The associated long.
/// </returns>
/// <exception cref="">NoSuchElementException is thrown if the key doesn't
/// map to an existing object.
/// </exception>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Long.
/// </exception>
/// <exception cref="">NumberFormatException is thrown if the value mapped
/// by the key has not a valid number format.
///
/// </exception>
public virtual long GetLong(String key) {
Int64 l = GetLong(key, DEFAULT_INT64);
if ((Object) l != null) {
return (long) l;
} else {
throw new Exception('\'' + key + "' doesn't map to an existing object");
}
}
/// <summary> Get a long associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <param name="defaultValue">The default value.
/// </param>
/// <returns>The associated long if key is found and has valid
/// format, default value otherwise.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Long.
/// </exception>
/// <exception cref="">NumberFormatException is thrown if the value mapped
/// by the key has not a valid number format.
///
/// </exception>
public virtual Int64 GetLong(String key, Int64 defaultValue) {
Object value_Renamed = this[key];
if (value_Renamed is Int64) {
return (Int64) value_Renamed;
} else if (value_Renamed is String) {
Int64 l = Int64.Parse((String) value_Renamed);
CollectionsUtil.PutElement(this, key, l);
return l;
} else if (value_Renamed == null) {
if (defaults != null) {
return defaults.GetLong(key, defaultValue);
} else {
return defaultValue;
}
} else {
throw new InvalidCastException('\'' + key + "' doesn't map to a Long object");
}
}
/// <summary> Get a float associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <returns>The associated float.
/// </returns>
/// <exception cref="">NoSuchElementException is thrown if the key doesn't
/// map to an existing object.
/// </exception>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Float.
/// </exception>
/// <exception cref="">NumberFormatException is thrown if the value mapped
/// by the key has not a valid number format.
///
/// </exception>
public virtual float GetFloat(String key) {
Single f = GetFloat(key, DEFAULT_SINGLE);
if ((Object) f != null) {
return (float) f;
} else {
throw new Exception('\'' + key + "' doesn't map to an existing object");
}
}
/// <summary> Get a float associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <param name="defaultValue">The default value.
/// </param>
/// <returns>The associated float if key is found and has valid
/// format, default value otherwise.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Float.
/// </exception>
/// <exception cref="">NumberFormatException is thrown if the value mapped
/// by the key has not a valid number format.
///
/// </exception>
public virtual Single GetFloat(String key, Single defaultValue) {
Object value_Renamed = this[key];
if (value_Renamed is Single) {
return (Single) value_Renamed;
} else if (value_Renamed is String) {
//UPGRADE_TODO: Format of parameters of constructor 'java.lang.Float.Float' are different in the equivalent in .NET. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1092"'
Single f = Single.Parse((String) value_Renamed);
CollectionsUtil.PutElement(this, key, f);
return f;
} else if (value_Renamed == null) {
if (defaults != null) {
return defaults.GetFloat(key, defaultValue);
} else {
return defaultValue;
}
} else {
throw new InvalidCastException('\'' + key + "' doesn't map to a Float object");
}
}
/// <summary> Get a double associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <returns>The associated double.
/// </returns>
/// <exception cref="">NoSuchElementException is thrown if the key doesn't
/// map to an existing object.
/// </exception>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Double.
/// </exception>
/// <exception cref="">NumberFormatException is thrown if the value mapped
/// by the key has not a valid number format.
///
/// </exception>
public virtual double GetDouble(String key) {
Double d = GetDouble(key, DEFAULT_DOUBLE);
if ((Object) d != null) {
return d;
} else {
throw new Exception('\'' + key + "' doesn't map to an existing object");
}
}
/// <summary> Get a double associated with the given configuration key.
/// *
/// </summary>
/// <param name="key">The configuration key.
/// </param>
/// <param name="defaultValue">The default value.
/// </param>
/// <returns>The associated double if key is found and has valid
/// format, default value otherwise.
/// </returns>
/// <exception cref="">ClassCastException is thrown if the key maps to an
/// object that is not a Double.
/// </exception>
/// <exception cref="">NumberFormatException is thrown if the value mapped
/// by the key has not a valid number format.
///
/// </exception>
public virtual Double GetDouble(String key, Double defaultValue) {
Object value_Renamed = this[key];
if (value_Renamed is Double) {
return (Double) value_Renamed;
} else if (value_Renamed is String) {
//UPGRADE_TODO: Format of parameters of constructor 'java.lang.Double.Double' are different in the equivalent in .NET. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1092"'
Double d = Double.Parse((String) value_Renamed);
CollectionsUtil.PutElement(this, key, d);
return d;
} else if (value_Renamed == null) {
if (defaults != null) {
return defaults.GetDouble(key, defaultValue);
} else {
return defaultValue;
}
} else {
throw new InvalidCastException('\'' + key + "' doesn't map to a Double object");
}
}
/// <summary> Convert a standard properties class into a configuration
/// class.
/// *
/// </summary>
/// <param name="p">properties object to convert into
/// a ExtendedProperties object.
/// *
/// </param>
/// <returns>ExtendedProperties configuration created from the
/// properties object.
///
/// </returns>
public static ExtendedProperties ConvertProperties(ExtendedProperties p) {
ExtendedProperties c = new ExtendedProperties();
for (IEnumerator e = (IEnumerator) p.Keys; e.MoveNext(); ) {
String key = (String) e.Current;
String value = p.GetProperty(key).ToString();
c.SetProperty(key, value);
}
return c;
}
}
}
|