////////////////////////////////////////////////////////////// /// <summary> /// This factory method returns the appropriate resolver to /// the consumer. The definition of "appropriate" is left /// to the implementation of the config resolver. /// </summary> /// <param name="key">the key to be tested</param> /// <param name="supplier">the potential new supplier</param> /// <param name="current">the current supplier</param> ////////////////////////////////////////////////////////////// public virtual IConfigResolver GetResolver(string key, IConfigSupplier supplier, IConfigResolver current) { IConfigResolver cr = null; if (_debug.IsActive) { _debug.WriteLine("template: getting resolver for key: " + key); _debug.WriteLine("template: supplier: " + supplier); _debug.WriteLine("template: current: " + current); } // only do something if the supplier can read the key if (supplier.CanRead(key)) { cr = new DefaultConfigResolver(key, supplier); } else { return(current); } // if we get here, the supplier can read the key, so // it is just a matter of hooking up the relationships if (current != null) { current.Parent = cr; cr = current; } return(cr); }
////////////////////////////////////////////////////////////// /// <summary> /// The constructor takes a reference to config supplier /// instance to decorate. /// </summary> /// <param name="key">the key being resolved</param> /// <param name="config">the supplier with the actual /// data</param> /// <param name="write">parameter is used to propagate the /// output supplier</param> ////////////////////////////////////////////////////////////// protected WriteCaptureConfigResolver(string key, IConfigSupplier config, IConfigSupplier write) : base(key, config) { _write = write; }
////////////////////////////////////////////////////////////// /// <summary> /// This factory method returns the appropriate resolver to /// the consumer. The definition of "appropriate" is left /// to the implementation of the config resolver. /// </summary> /// <param name="key">the key to be tested</param> /// <param name="supplier">the potential new supplier</param> /// <param name="current">the current supplier</param> ////////////////////////////////////////////////////////////// public override IConfigResolver GetResolver(string key, IConfigSupplier supplier, IConfigResolver current) { // unfortunately, this is pretty much cut-n-paste code // reuse from the base class... :( IConfigResolver cr = null; // only do something if the supplier can read the key if (supplier.CanRead(key)) { cr = new WriteCaptureConfigResolver(key, supplier, _write); } else { return(current); } // if we get here, the supplier can read the key, so // it is just a matter of hooking up the relationships if (current != null) { current.Parent = cr; cr = current; } return(cr); }
////////////////////////////////////////////////////////////// /// <summary> /// The constructor takes a reference to config supplier /// instance to decorate. /// </summary> /// <param name="key">the key being resolved</param> /// <param name="config">the supplier with the actual /// data</param> ////////////////////////////////////////////////////////////// protected DefaultConfigResolver(string key, IConfigSupplier config) { _key = key; _config = config; _debug = new DebugWriter(this); _debug.WriteLine( string.Format("created resolver {0}:{1} = '{2}'", config, key, config[key])); }
////////////////////////////////////////////////////////////// /// <summary> /// This method is used to determine if the key can be /// written to this supplier. /// </summary> /// <param name="key">the key to check</param> /// <returns>true if the key can be written by this /// supplier</returns> ////////////////////////////////////////////////////////////// public bool CanWrite(string key) { IConfigSupplier cs = (IConfigSupplier)_hash[key]; if (cs != null) { return(cs.CanWrite(key)); } return(false); }
////////////////////////////////////////////////////////////// /// <summary> /// This method is used to serialize the IConfigSupplier to a /// format which more-or-less follows the key=value form /// </summary> ////////////////////////////////////////////////////////////// public static string ConfigToPropertiesString(IConfigSupplier dict) { StringBuilder buf = new StringBuilder(); foreach (string key in dict.Keys) { buf.Append(key); buf.Append("="); buf.Append(dict[key]); buf.Append("\n"); } return(buf.ToString()); }
////////////////////////////////////////////////////////////// /// <summary> /// This method is used to allow the instance to load the /// settings once it has been created. Each instance can /// have its own trace level independently controlled. /// </summary> /// <param name="props">the supplier</param> ////////////////////////////////////////////////////////////// public void LoadInstanceSettings(string name, IConfigSupplier props) { String pname = "errortrace." + name + ".tracelevel"; String s = props[pname]; if (s == null) { pname = string.Concat(name, ".tracelevel"); s = props[pname]; } if (s != null) { TraceLevel = int.Parse(s); } }
////////////////////////////////////////////////////////////// /// <summary> /// This method is used to register a configuration supplier /// for this application. /// </summary> ////////////////////////////////////////////////////////////// public void RegisterConfigSupplier(IConfigSupplier supplier) { if (supplier.AppName != null && _name != supplier.AppName) { //Console.WriteLine("supplier name: '{0}'", supplier.AppName); //Console.WriteLine("my name: '{0}'", _name); //Console.WriteLine("skipped"); // don't do anything if the names don't match return; } foreach (string key in supplier.Keys) { _hash[key] = _template.GetResolver(key, supplier, (IConfigResolver)_hash[key]); } _suppliers.Add(supplier); }
////////////////////////////////////////////////////////////// /// <summary> /// This method is used to load all of the confiuration /// settings from the specified IConfigSupplier. /// </summary> /// <param name="props">the supplier</param> ////////////////////////////////////////////////////////////// public static void LoadSettings(IConfigSupplier props) { lock (_props) { if (!_props.Equals(props)) { foreach (string key in props.Keys) { _props[key] = props[key]; } } } // FIXME: need to eliminate the get bool check // cut-n-paste!!! string s = props["errortrace.tracefile"]; if (s != null) { string a = props["errortrace.append"]; bool append = true; if (a != null) { char c = a.ToLower()[0]; if (c != 'y' && c != 't') { append = false; } } SetTraceFile(s, append); } s = props["errortrace.showts"]; if (s != null) { char c = s.ToLower()[0]; if (c != 'y' && c != 't') { ShowTimestamp = false; } } s = props["errortrace.showthreadalways"]; if (s != null) { char c = s.ToLower()[0]; if (c != 'y' && c != 't') { ShowThreadNameAlways = false; } } s = props["errortrace.tsfmt"]; if (s != null) { TimestampFormat = s; } s = props["errortrace.tracelevel"]; if (s != null) { GlobalTraceLevel = int.Parse(s); } // take care of the instances foreach (string key in _tracers.Keys) { TraceCore tc = (TraceCore)_tracers[key]; tc.LoadInstanceSettings(key, props); } }
////////////////////////////////////////////////////////////// /// <summary> /// This method is used to register a configuration supplier /// for this application. /// </summary> ////////////////////////////////////////////////////////////// public void UnregisterConfigSupplier(IConfigSupplier supplier) { // FIXME: figure out how to implement this cleanly }
////////////////////////////////////////////////////////////// /// <summary> /// This method writes the config supplier in property /// format to the specified TextWriter. /// </summary> /// <param name="writer">the writer to use</param> /// <param name="config">the supplier to write</param> /// <exception class="System.IO.IOException">if the write /// fails</exception> ////////////////////////////////////////////////////////////// public static void WriteConfigAsProperties(TextWriter writer, IConfigSupplier dict) { writer.Write(ConfigToPropertiesString(dict)); }
////////////////////////////////////////////////////////////// /// <summary> /// This method is used to register a config supplier. /// </summary> /// <param name="supplier">the supplier to register</param> ////////////////////////////////////////////////////////////// public static void RegisterSupplier(IConfigSupplier supplier) { AppConfig ac = GetConfig(supplier.AppName); ac.RegisterConfigSupplier(supplier); }
////////////////////////////////////////////////////////////// /// <summary> /// This constructor creates an empty instance which is used /// as a template. /// </summary> /// <param name="config">the supplier to use for /// writing</param> ////////////////////////////////////////////////////////////// public WriteCaptureConfigResolver(IConfigSupplier write) { _write = write; }