/******************************************************************************* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"). You may not use * this file except in compliance with the License. A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. * ***************************************************************************** * __ _ _ ___ * ( )( \/\/ )/ __) * /__\ \ / \__ \ * (_)(_) \/\/ (___/ * * AWS SDK for .NET * */ using System; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Configuration; using System.Diagnostics; using System.Linq; using Amazon.Runtime.Internal.Util; using Amazon.Util; using System.Xml; using System.Reflection; using System.Text; namespace Amazon { /// /// Configuration options that apply to the entire SDK. /// public static partial class AWSConfigs { #region ApplicationName /// /// The unique application name for the current application. This values is currently used /// by high level APIs (Mobile Analytics Manager and Cognito Sync Manager) to create a unique file /// path to store local database files. /// Changes to this setting will only take effect in newly-constructed objects using this property. /// /// <configSections> /// <section name="aws" type="Amazon.AWSSection, AWSSDK.Core"/> /// </configSections> /// <aws applicationName="" /> /// /// public static string ApplicationName { get { return _rootConfig.ApplicationName; } set { _rootConfig.ApplicationName = value; } } #endregion #region Config public static string GetConfig(string name) { NameValueCollection appConfig = ConfigurationManager.AppSettings; if (appConfig == null) return null; string value = appConfig[name]; return value; } internal static T GetSection(string sectionName) where T : class, new() { object section = ConfigurationManager.GetSection(sectionName); if (section == null) return new T(); return section as T; } internal static bool XmlSectionExists(string sectionName) { var section = ConfigurationManager.GetSection(sectionName); var element = section as System.Xml.XmlElement; return (element != null); } #endregion #region TraceListeners private static Dictionary> _traceListeners = new Dictionary>(StringComparer.OrdinalIgnoreCase); /// /// Add a listener for SDK logging. /// /// If the listener does not have a name, you will not be able to remove it later. /// The source to log for, e.g. "Amazon", or "Amazon.DynamoDB". /// The listener to add. public static void AddTraceListener(string source, TraceListener listener) { if (string.IsNullOrEmpty(source)) throw new ArgumentException("Source cannot be null or empty", "source"); if (null == listener) throw new ArgumentException("Listener cannot be null", "listener"); lock (_traceListeners) { if (!_traceListeners.ContainsKey(source)) _traceListeners.Add(source, new List()); _traceListeners[source].Add(listener); } Logger.ClearLoggerCache(); } /// /// Remove a trace listener from SDK logging. /// /// The source the listener was added to. /// The name of the listener. public static void RemoveTraceListener(string source, string name) { if (string.IsNullOrEmpty(source)) throw new ArgumentException("Source cannot be null or empty", "source"); if (string.IsNullOrEmpty(name)) throw new ArgumentException("Name cannot be null or empty", "name"); lock (_traceListeners) { if (_traceListeners.ContainsKey(source)) { foreach (var l in _traceListeners[source]) { if (l.Name.Equals(name, StringComparison.Ordinal)) { _traceListeners[source].Remove(l); break; } } } } Logger.ClearLoggerCache(); } // Used by Logger.Diagnostic to add listeners to TraceSources when loggers // are created. internal static TraceListener[] TraceListeners(string source) { lock (_traceListeners) { List temp; if (_traceListeners.TryGetValue(source, out temp)) { return temp.ToArray(); } return new TraceListener[0]; } } #endregion #region Generate Config Template /// /// Generates a sample XML representation of the SDK configuration section. /// /// /// The XML returned has an example of every tag in the SDK configuration /// section, and sample input for each attribute. This can be included in /// an App.config or Web.config and edited to suit. Where a section contains /// a collection, multiple of the same tag will be output. /// /// Sample XML configuration string. public static string GenerateConfigTemplate() { Assembly a = typeof(AWSConfigs).Assembly; Type t = a.GetType("Amazon.AWSSection"); var xmlSettings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true, IndentChars = " ", NewLineOnAttributes = true, NewLineChars = "\n" }; var sb = new StringBuilder(); using (var xml = XmlWriter.Create(sb, xmlSettings)) { FormatConfigSection(t, xml, tag: "aws"); } return sb.ToString(); } private static void FormatConfigSection(Type section, XmlWriter xml, string tag = null) { var props = section.GetProperties( BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); var attrs = props.Where(p => !IsConfigurationElement(p)).ToList(); var subsections = props.Where(p => IsConfigurationElement(p) && !IsConfigurationElementCollection(p)).ToList(); var collections = props.Where(p => IsConfigurationElementCollection(p)).ToList(); xml.WriteStartElement(tag); foreach (var prop in attrs) { var name = ConfigurationPropertyName(prop); xml.WriteAttributeString(name, GetExampleForType(prop)); } foreach (var prop in subsections) { var sectionName = ConfigurationPropertyName(prop); if (!string.IsNullOrEmpty(sectionName)) FormatConfigSection(prop.PropertyType, xml, sectionName); } foreach (var coll in collections) { FormatConfigurationListItems(coll, xml); } xml.WriteEndElement(); } private static string GetExampleForType(PropertyInfo prop) { if (prop.PropertyType.Equals(typeof(bool?))) return "true | false"; if (prop.PropertyType.Equals(typeof(int?))) return "1234"; if (prop.PropertyType.Equals(typeof(String))) return "string value"; if (prop.PropertyType.Equals(typeof(Type))) return "NameSpace.Class, Assembly"; if (prop.PropertyType.IsEnum) { var members = Enum.GetNames(prop.PropertyType); var separator = IsFlagsEnum(prop) ? ", " : " | "; return string.Join(separator, members.ToArray()); } return "( " + prop.PropertyType.FullName + " )"; } private static void FormatConfigurationListItems(PropertyInfo section, XmlWriter xml) { var sectionName = ConfigurationPropertyName(section); var itemType = TypeOfConfigurationCollectionItem(section); var item = Activator.CreateInstance(section.PropertyType); var nameProperty = section.PropertyType.GetProperty("ItemPropertyName", BindingFlags.NonPublic | BindingFlags.Instance); var itemTagName = nameProperty.GetValue(item, null).ToString(); FormatConfigSection(itemType, xml, itemTagName); FormatConfigSection(itemType, xml, itemTagName); } private static bool IsFlagsEnum(PropertyInfo prop) { return prop.PropertyType.GetCustomAttributes(typeof(FlagsAttribute), false).Any(); } private static bool IsConfigurationElement(PropertyInfo prop) { return typeof(ConfigurationElement).IsAssignableFrom(prop.PropertyType); } private static bool IsConfigurationElementCollection(PropertyInfo prop) { return typeof(ConfigurationElementCollection).IsAssignableFrom(prop.PropertyType); } private static Type TypeOfConfigurationCollectionItem(PropertyInfo prop) { var configCollAttr = prop.PropertyType .GetCustomAttributes(typeof(ConfigurationCollectionAttribute), false) .First(); return ((ConfigurationCollectionAttribute)configCollAttr).ItemType; } private static string ConfigurationPropertyName(PropertyInfo prop) { var configAttr = prop.GetCustomAttributes(typeof(ConfigurationPropertyAttribute), false) .FirstOrDefault() as ConfigurationPropertyAttribute; return null == configAttr ? prop.Name : configAttr.Name; } #endregion } }