示例#1
0
        /// <summary>
        /// Checks the command line params.<para/>
        /// arguments format: key=value or --key value
        /// </summary>
        /// <param name="args">The args.</param>
        public FlexibleOptions Parse(string[] args)
        {
            // 1. parse local configuration file
            // display the options listed in the configuration file
            FlexibleOptions localOptions = ParseAppSettings();

            // 2. parse console arguments
            // parse arguments like: key=value
            FlexibleOptions argsOptions = ParseCommandLineArguments(args);

            // 3. merge arguments with app.config options. Priority: arguments > app.config
            Parsed = FlexibleOptions.Merge(localOptions, argsOptions);

            // 4. check for external config file
            // set config alias
            Parsed.SetAlias("config", "S3ConfigurationPath", "webConfigurationFile");

            // load and parse web hosted configuration file (priority order: argsOptions > localOptions)
            ExternalFiles = Parsed.GetAsList("config", new char[] { ',', ';' });
            FlexibleOptions externalLoadedOptions = ParseExternalFiles(ExternalFiles);

            // 5. merge options with the following priority:
            // 1. console arguments
            // 2. external file with json configuration object (local or web)
            // 3. local configuration file (app.config or web.config)
            Parsed = FlexibleOptions.Merge(Parsed, externalLoadedOptions, argsOptions);

            // return final merged options
            return(Parsed);
        }
示例#2
0
        public FlexibleOptions ParseExternalFiles(string[] filePaths)
        {
            // load and parse web hosted configuration file (priority order: argsOptions > localOptions)
            FlexibleOptions parsed = null;

            try
            {
                ExternalFiles = filePaths;
                foreach (var file in filePaths)
                {
                    var loaded = LoadExtenalConfigurationFile(file.Trim(' ', '\'', '"', '[', ']'));
                    if (parsed == null)
                    {
                        parsed = loaded;
                    }
                    else
                    {
                        parsed.AddRange(loaded);
                    }
                }
            }
            catch (Exception ex)
            {
                if (ThrownOnError)
                {
                    throw;
                }
                RaiseErrorEvent(ex);
            }
            return(parsed);
        }
示例#3
0
        private static FlexibleOptions parseFile (string content)
        {
            var options = new FlexibleOptions ();

            // detect xml
            if (content.TrimStart ().StartsWith ("<"))
            {
                var xmlDoc = System.Xml.Linq.XDocument.Parse (content);
                var root = xmlDoc.Descendants ("config").FirstOrDefault ();
                if (root != null && root.HasElements)
                {
                    foreach (var i in root.Elements ())
                    {
                        options.Set (i.Name.ToString (), i.Value);
                    }
                }
            }
            else
            {
                var json = Newtonsoft.Json.Linq.JObject.Parse (content);
                foreach (var i in json)
                {
                    options.Set (i.Key, i.Value.ToString (Newtonsoft.Json.Formatting.None));
                }
            }
            return options;
        }
示例#4
0
        /// <summary>
        /// Parses command line and app.config arguments and initilialize log.
        /// </summary>
        /// <param name="args">Program arguments</param>
        /// <param name="thrownOnError">The thrown exception on internal initialization error.</param>
        /// <param name="options">The additional options.</param>
        /// <returns>Parsed arguments</returns>
        public static FlexibleOptions Initialize (string[] args, bool thrownOnError, InitializationOptions options = null)
        {
            InitOptions = options;
            // run default program initialization
            DefaultProgramInitialization ();

            // parse command line arguments
            ProgramOptions = CheckCommandLineParams (args, thrownOnError);

            // check for help command
            if (ProgramOptions.Get<bool> ("help", false) || ProgramOptions.Get<bool> ("h", false))
            {
                show_help ("");
                CloseApplication (0, true);
            }

            // display program initialization header
            if (!Console.IsOutputRedirected)
            {
                ConsoleUtils.DisplayHeader (
                    typeof(ConsoleUtils).Namespace.Replace (".SimpleHelpers", ""),
                    "options: " + (ProgramOptions == null ? "none" : "\n#    " + String.Join ("\n#    ", ProgramOptions.Options.Select (i => i.Key + "=" + i.Value))));
            }
            else
            {
                var logger = GetLogger ();
                if (logger.IsDebugEnabled)
                {
                    logger.Debug ("options: " + (ProgramOptions == null ? "none" : "\n#    " + String.Join ("\n#    ", ProgramOptions.Options.Select (i => i.Key + "=" + i.Value))));
                }
            }

            return ProgramOptions;
        }
        /// <summary>
        /// Merge together FlexibleOptions instances, the last object in the list has priority in conflict resolution (overwrite).<para/>
        /// Merge will return a new instance of FlexibleOptions.
        /// </summary>
        /// <param name="items"></param>
        /// <returns>A new instance of FlexibleOptions with merged options</returns>
        public static FlexibleOptions Merge(params FlexibleOptions[] items)
        {
            if (items == null || items.Length == 0)
            {
                return(new FlexibleOptions());
            }
            // create options
            var lastItem = items.LastOrDefault(i => i != null);
            var merge    = new FlexibleOptions(lastItem != null ? lastItem._caseInsensitive : true);
            // merge
            var dic = merge.Options;

            for (int i = 0; i < items.Length; i++)
            {
                if (items[i] == null)
                {
                    continue;
                }
                // copy
                foreach (var o in items[i].Options)
                {
                    dic[o.Key] = o.Value;
                }
                // also copy alias values
                if (items[i]._alias != null)
                {
                    foreach (var a in items[i]._alias)
                    {
                        merge.SetAlias(a.Value, a.Key);
                    }
                }
            }
            return(merge);
        }
示例#6
0
        private FlexibleOptions ParseFileContent(string content)
        {
            var options = new FlexibleOptions();

            if (String.IsNullOrEmpty(content))
            {
                return(options);
            }
            // prepare content
            content = content.Trim();
            try
            {
                // detect xml
                if (content.StartsWith("<"))
                {
                    var xmlDoc = System.Xml.Linq.XDocument.Parse(content);
                    var root   = xmlDoc.Descendants("config").FirstOrDefault();
                    if (root != null && root.HasElements)
                    {
                        foreach (var i in root.Elements())
                        {
                            options.Set(i.Name.ToString(), i.Value);
                        }
                    }
                }
                // parse as json
                else
                {
                    var json = Newtonsoft.Json.Linq.JObject.Parse(content);
                    foreach (var i in json)
                    {
                        options.Set(i.Key, i.Value.ToString(Newtonsoft.Json.Formatting.None));
                    }
                }
            }
            catch (Exception ex)
            {
                if (ThrownOnError)
                {
                    throw;
                }
                RaiseErrorEvent(ex);
                return(null);
            }
            return(options);
        }
示例#7
0
        public FlexibleOptions ParseCommandLineArguments(string[] args)
        {
            var argsOptions = new FlexibleOptions();

            if (args != null)
            {
                string arg;
                bool   openTag = false;
                string lastTag = null;
                for (int ix = 0; ix < args.Length; ix++)
                {
                    arg = args[ix];
                    // check for option with key=value sintax (restriction: the previous tag must not be an open tag)
                    // also valid for --key:value
                    bool hasStartingMarker = arg.StartsWith("-", StringComparison.Ordinal) || arg.StartsWith("/", StringComparison.Ordinal);
                    int  p = arg.IndexOf('=');
                    if (p > 0 && (hasStartingMarker || !openTag))
                    {
                        argsOptions.Set(arg.Substring(0, p).Trim().TrimStart('-', '/'), arg.Substring(p + 1).Trim());
                        lastTag = null;
                        openTag = false;
                    }
                    // search for tag stating with special character
                    // a linux path should be valid: -path /home/file
                    else if (hasStartingMarker && !(openTag && arg[0] == '/'))
                    {
                        lastTag = arg.Trim().TrimStart('-', '/');
                        argsOptions.Set(lastTag, "true");
                        openTag = true;
                    }
                    // set value of last tag
                    else if (lastTag != null)
                    {
                        argsOptions.Set(lastTag, arg.Trim());
                        openTag = false;
                    }
                }
            }
            return(argsOptions);
        }
示例#8
0
        /// <summary>
        /// Merge together FlexibleOptions instances, the last object in the list has priority in conflict resolution (overwrite).<para/>
        /// Merge will return a new instance of FlexibleOptions.
        /// </summary>
        /// <param name="items"></param>
        /// <returns>A new instance of FlexibleOptions with merged options</returns>
        public static FlexibleOptions Merge(params FlexibleOptions[] items)
        {
            var merge = new FlexibleOptions();

            if (items == null || items.Length == 0)
            {
                return(merge);
            }
            var dic = merge.Options;

            for (int i = 0; i < items.Length; i++)
            {
                if (items[i] == null)
                {
                    continue;
                }
                foreach (var o in items[i].Options)
                {
                    dic[o.Key] = o.Value;
                }
            }
            return(merge);
        }
示例#9
0
        public FlexibleOptions ParseAppSettings()
        {
            // parse local configuration file
            // display the options listed in the configuration file
            var localOptions = new FlexibleOptions();

            try
            {
                var appSettings = System.Configuration.ConfigurationManager.AppSettings;
                foreach (var k in appSettings.AllKeys)
                {
                    localOptions.Set(k, appSettings[k]);
                }
            }
            catch (Exception appSettingsEx)
            {
                if (ThrownOnError)
                {
                    throw;
                }
                RaiseErrorEvent(appSettingsEx);
            }
            return(localOptions);
        }
示例#10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FlexibleOptions" /> class.
 /// </summary>
 /// <param name="instance">Another FlexibleObject instance to be cloned.</param>
 /// <param name="caseInsensitive">If the intenal dictionary should have case insensitive keys.</param>
 public FlexibleOptions(FlexibleOptions instance, bool caseInsensitive)
 {
     _caseInsensitive = caseInsensitive;
     Options          = new Dictionary <string, string> (instance.Options, _caseInsensitive ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal);
 }
示例#11
0
        /// <summary>
        /// Checks the command line params.<para/>
        /// arguments format: key=value or --key value
        /// </summary>
        /// <param name="args">The args.</param>
        internal static FlexibleOptions CheckCommandLineParams (string[] args, bool thrownOnError)
        {
            FlexibleOptions mergedOptions = null;
            FlexibleOptions argsOptions = null;
            FlexibleOptions localOptions = new FlexibleOptions ();
            FlexibleOptions externalLoadedOptions = null;

            try
            {

                // parse local configuration file
                // display the options listed in the configuration file                 
                try
                {
                    var appSettings = System.Configuration.ConfigurationManager.AppSettings;
                    foreach (var k in appSettings.AllKeys)
                    {
                        localOptions.Set (k, appSettings[k]);
                    }
                }

                catch (Exception appSettingsEx)
                {
                    if (thrownOnError)
                        throw;
                    GetLogger ().Warn (appSettingsEx);
                }

                // parse console arguments
                // parse arguments like: key=value
                argsOptions = ParseCommandLineArguments (args);

                // merge arguments with app.config options. Priority: arguments > app.config
                mergedOptions = FlexibleOptions.Merge (localOptions, argsOptions);
                // adjust alias for web hosted configuration file
                if (String.IsNullOrEmpty (mergedOptions.Get ("config")))
                    mergedOptions.Set ("config", mergedOptions.Get ("S3ConfigurationPath", mergedOptions.Get ("webConfigurationFile")));

                // load and parse web hosted configuration file (priority order: argsOptions > localOptions)
                string externalConfigFile = mergedOptions.Get ("config", "");
                bool configAbortOnError = mergedOptions.Get ("configAbortOnError", true);
                if (!String.IsNullOrWhiteSpace (externalConfigFile))
                {
                    foreach (var file in externalConfigFile.Trim(' ', '\'', '"', '[', ']').Split (',', ';'))
                    {
                        GetLogger ().Debug ("Loading configuration file from {0} ...", externalConfigFile);
                        externalLoadedOptions = FlexibleOptions.Merge (externalLoadedOptions, LoadExtenalConfigurationFile (file.Trim (' ', '\'', '"'), configAbortOnError));
                    }
                }
            }
            catch (Exception ex)
            {
                // initialize log before dealing with exceptions
                if (mergedOptions != null)
                    InitializeLog (mergedOptions.Get ("logFilename"), mergedOptions.Get ("logLevel", "Info"), InitOptions, mergedOptions);
                if (thrownOnError)
                    throw;
                GetLogger ().Error (ex);
            }

            // merge options with the following priority:
            // 1. console arguments
            // 2. external file with json configuration object (local or web)
            // 3. local configuration file (app.config or web.config)
            mergedOptions = FlexibleOptions.Merge (mergedOptions, externalLoadedOptions, argsOptions);

            // reinitialize log options if different from local configuration file
            InitializeLog (mergedOptions.Get ("logFilename"), mergedOptions.Get ("logLevel", "Info"), InitOptions, mergedOptions);

            // return final merged options
            ProgramOptions = mergedOptions;
            return mergedOptions;
        }
示例#12
0
        /// <summary>
        /// Log initialization.
        /// </summary>
        internal static void InitializeLog (string logFileName = null, string logLevel = null, InitializationOptions initOptions = null, FlexibleOptions appOptions = null)
        {
            // default parameters initialization from config file
            if (String.IsNullOrEmpty (logFileName))
                logFileName = _logFileName ?? System.Configuration.ConfigurationManager.AppSettings["logFilename"];
			if (String.IsNullOrEmpty (logFileName))
                logFileName = ("${basedir}/log/" + typeof (ConsoleUtils).Namespace.Replace (".SimpleHelpers", "") + ".log");
            if (String.IsNullOrEmpty (logLevel))
                logLevel = _logLevel ?? (System.Configuration.ConfigurationManager.AppSettings["logLevel"] ?? "Info");

            // check if log was initialized with same options
            if (_logFileName == logFileName && _logLevel == logLevel)
                return;

            // try to parse loglevel
            LogLevel currentLogLevel;
            try { currentLogLevel = LogLevel.FromString (logLevel); }
            catch { currentLogLevel = LogLevel.Info; }

            // save current log configuration
            _logFileName = logFileName;
            _logLevel = currentLogLevel.ToString ();

            // check initialization options
            var localOptions = initOptions != null ? initOptions.Clone () : new InitializationOptions ();
            // adjust options based on arguments
            if (appOptions != null)
            {
                if (!localOptions.DisableLogFile.HasValue && appOptions.HasOption ("DisableLogFile"))
                    localOptions.DisableLogFile = appOptions.Get ("DisableLogFile", false);
                if (localOptions.EnableLogTargets == null && !String.IsNullOrEmpty (appOptions.Get ("EnableLogTargets")))
                    localOptions.EnableLogTargets = appOptions.GetAsList ("EnableLogTargets").Where (i => !String.IsNullOrWhiteSpace (i)).Select (i => i.Trim ()).ToArray ();
                if (localOptions.DisableLogTargets == null && !String.IsNullOrEmpty (appOptions.Get ("DisableLogTargets")))
                    localOptions.DisableLogTargets = appOptions.GetAsList ("DisableLogTargets").Where (i => !String.IsNullOrWhiteSpace (i)).Select (i => i.Trim ()).ToArray ();
            }

            // prepare list of enabled targets
            HashSet<string> enabledTargets;
            // if enabled log targets was provided, use it!
            if (localOptions.EnableLogTargets != null && localOptions.EnableLogTargets.Count > 0)
            {
                enabledTargets = new HashSet<string> (localOptions.EnableLogTargets, StringComparer.OrdinalIgnoreCase);
            }
            // else we remove disabled target...
            else
            {
                enabledTargets = new HashSet<string> (StringComparer.OrdinalIgnoreCase) { "console", "file" };
                // set enabled targets
                if (localOptions.Targets != null)
                {
                    foreach (var i in localOptions.Targets)
                    {
                        foreach (var n in GetNLogTargetName (i))
                            enabledTargets.Add (n);
                    }
                }
                // remove disabled targets
                if (localOptions.DisableLogTargets != null)
                    foreach (var i in localOptions.DisableLogTargets)
                        enabledTargets.Remove (i);
                if (localOptions.DisableLogFile ?? false)
                    enabledTargets.Remove ("file");                
            }

            // prepare log configuration
            var config = new NLog.Config.LoggingConfiguration ();

            // console output
            if (!Console.IsOutputRedirected && enabledTargets.Contains ("console"))
            {
                var consoleTarget = new NLog.Targets.ColoredConsoleTarget ();
                consoleTarget.Layout = "${longdate}\t${callsite}\t${level}\t${message}\t${onexception: \\:[Exception] ${exception:format=tostring}}";

                config.AddTarget ("console", consoleTarget);

                var rule1 = new NLog.Config.LoggingRule ("*", LogLevel.Trace, consoleTarget);
                config.LoggingRules.Add (rule1);
            }

            // file output
            if (enabledTargets.Contains ("file"))
            {
                var fileTarget = new NLog.Targets.FileTarget ();
                fileTarget.FileName = logFileName;
                fileTarget.Layout = "${longdate}\t${callsite}\t${level}\t\"${message}${onexception: \t [Exception] ${exception:format=tostring}}\"";
                fileTarget.ConcurrentWrites = true;
                fileTarget.ConcurrentWriteAttemptDelay = 10;
                fileTarget.ConcurrentWriteAttempts = 8;
                fileTarget.AutoFlush = true;
                fileTarget.KeepFileOpen = true;
                fileTarget.DeleteOldFileOnStartup = false;
                fileTarget.ArchiveAboveSize = (localOptions.MaxLogFileSize > 0) ? localOptions.MaxLogFileSize : 4 * 1024 * 1024;  // 4 Mb
                fileTarget.MaxArchiveFiles = (localOptions.MaxArchiveLogFiles > 0) ? localOptions.MaxArchiveLogFiles : 10;
                fileTarget.ArchiveNumbering = NLog.Targets.ArchiveNumberingMode.DateAndSequence;
                fileTarget.ArchiveDateFormat = "yyyyMMdd";
                fileTarget.ArchiveFileName = System.IO.Path.ChangeExtension (logFileName, ".{#}" + System.IO.Path.GetExtension (logFileName));

                // set file output to be async (commented out since doesn't work well on mono)
                // var wrapper = new NLog.Targets.Wrappers.AsyncTargetWrapper (fileTarget);

                config.AddTarget ("file", fileTarget);

                // configure log from configuration file
                var rule2 = new NLog.Config.LoggingRule ("*", currentLogLevel, fileTarget);
                config.LoggingRules.Add (rule2);
            }

            // External Log Target
            if (localOptions.Targets != null)
            {
                foreach (var t in localOptions.Targets)
                {
                    if (GetNLogTargetName (t).Any (i => enabledTargets.Contains (i)))
                    {
                        config.AddTarget (t);
                        config.LoggingRules.Add (new NLog.Config.LoggingRule ("*", currentLogLevel, t));
                    }
                }
            }

            // set configuration options
            LogManager.Configuration = config;
        }
 /// <summary>
 /// Adds another FlexibleOptions overwriting existing conflicting values.
 /// </summary>
 /// <param name="item">The item.</param>
 public void AddRange(FlexibleOptions item)
 {
     AddRange(item.Options);
 }