Exemplo n.º 1
0
        public void Load()
        {
            Log.Info("Loading rules");

            using (var progress = Display.StartProgress("Loading rules"))
            {
                long total   = context.Plugins.Count;
                long current = 0;

                foreach (var pluginFileName in context.Plugins.Select(p => p.FileName))
                {
                    bool retry;
                    do
                    {
                        retry = false;
                        try
                        {
                            var compiler = new RuleCompiler(this, pluginFileName);

                            string path  = Path.Combine(Program.ProgramFolder, Program.ProgramRulesFolder, RulesFolder, pluginFileName);
                            var    files = Context.DataFileProvider.FindDataFiles(path, "*.rules").ToArray();

                            total += files.Length;

                            foreach (var file in files)
                            {
                                using (var stream = file.Open())
                                {
                                    bool isDebugModeEnabled = DebugAll ||
                                                              pluginFileName.Equals(DebugPluginFileName, StringComparison.OrdinalIgnoreCase) &&
                                                              (DebugRuleFileName == null || Path.GetFileName(file.Name).Equals(DebugRuleFileName, StringComparison.OrdinalIgnoreCase));

                                    int count = 0;
                                    using (RuleReader reader = new RuleReader(stream))
                                    {
                                        foreach (var entry in reader.ReadRules())
                                        {
                                            if (entry.Select == null && entry.Update == null && entry.Inserts.Count() == 0)
                                            {
                                                Log.Warning("Rule {0} in file {1} ignored because it lacks any operation", entry.Name, pluginFileName);
                                                continue;
                                            }

                                            var metadata = new RuleMetadata()
                                            {
                                                PluginFileName = pluginFileName,
                                                RuleFileName   = Path.GetFileName(file.Name),
                                                Name           = entry.Name,
                                                Description    = entry.Description,
                                            };

                                            Log.Fine("Loading rule {0}\\{1}@{2}", metadata.PluginFileName, metadata.RuleFileName, metadata.Name);

                                            try
                                            {
                                                compiler.Add(entry, metadata, isDebugModeEnabled);
                                            }
                                            catch (IllegalTokenException ex)
                                            {
                                                Display.ShowProblems("Illegal Token", ex.ToString(), new Problem()
                                                {
                                                    Message  = ex.Message,
                                                    File     = file.GetRelativePath(),
                                                    Solution = string.Format("Please avoid using the following tokens in rule code: {0}",
                                                                             string.Join(", ", RuleCompiler.GetIllegalCodeTokens()))
                                                });
                                                throw;
                                            }

                                            count++;
                                        }
                                    }
                                    Log.Fine("Loaded {0} rule(s) from file {1}", count, stream.Name);
                                }

                                progress.Update(current, total, string.Format("{0}\\{1}", pluginFileName, Path.GetFileName(file.Name)));
                            }

                            if (compiler.HasRules)
                            {
                                try
                                {
                                    compiler.CompileAll();
                                }
                                catch (CompilerException ex)
                                {
                                    StringBuilder  text     = new StringBuilder();
                                    List <Problem> problems = new List <Problem>();
                                    foreach (System.CodeDom.Compiler.CompilerError error in ex.Errors)
                                    {
                                        if (!error.IsWarning)
                                        {
                                            text.AppendLine(error.ToString());

                                            problems.Add(new Problem()
                                            {
                                                Message  = string.Format("{0}: {1}", error.ErrorNumber, error.ErrorText),
                                                File     = DataFile.GetRelativePath(error.FileName),
                                                Line     = error.Line,
                                                Column   = error.Column,
                                                Solution = RuleCompiler.GetCompilerErrorHint(error)
                                            });
                                        }
                                    }
                                    text.Append(ex.ToString());

                                    Display.ShowProblems("Compiler Error(s)", text.ToString(), problems.ToArray());

                                    throw ex;
                                }

                                rules.Add(pluginFileName, new List <IRule>(compiler.CompiledRules));
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error("Error occured while loading rules for plugin {0} with message: {1}", pluginFileName, ex.Message);
                            Log.Fine(ex.ToString());

                            // Depending on the kind of error, offer a choice to reload rules for this plugin
                            // Rules can be reloaded only if illegal tokens have been detected or when compilation has failed
                            ChoiceOption result = ChoiceOption.Cancel;
                            if (ex.GetType() == typeof(IllegalTokenException) || ex.GetType() == typeof(CompilerException))
                            {
                                result = Display.Choice(string.Format("Try loading rules for plugin {0} again?", pluginFileName), ChoiceOption.Yes, ChoiceOption.Continue, ChoiceOption.Cancel);
                            }
                            else
                            {
                                result = Display.Choice("Continue loading rules?", ChoiceOption.Continue, ChoiceOption.Cancel);
                            }

                            if (result == ChoiceOption.Yes)
                            {
                                Log.Info("Rules for plugin {0} will be reloaded.", pluginFileName);
                                retry = true;
                            }
                            else if (result == ChoiceOption.Continue)
                            {
                                Log.Warning("Rules for plugin {0} skipped because an error occured: {1} ", pluginFileName, ex.Message);
                            }
                            else
                            {
                                Log.Warning("Rule loading has been aborted.");
                                throw new UserAbortException("Rule loading has been aborted by the user.");
                            }
                        }
                        finally
                        {
                            Display.ClearProblems();
                        }
                    } while (retry);
                }

                current++;
            }
        }
Exemplo n.º 2
0
        public void Load()
        {
            Log.Info("Loading rules");

            using (var progress = Display.StartProgress("Loading rules"))
            {
                long total = context.Plugins.Count;
                long current = 0;

                foreach (var pluginFileName in context.Plugins.Select(p => p.FileName))
                {
                    bool retry;
                    do
                    {
                        retry = false;
                        try
                        {
                            var compiler = new RuleCompiler(this, pluginFileName);

                            string path = Path.Combine(Program.ProgramFolder, Program.ProgramRulesFolder, RulesFolder, pluginFileName);
                            var files = Context.DataFileProvider.FindDataFiles(path, "*.rules").ToArray();

                            total += files.Length;

                            foreach (var file in files)
                            {
                                using (var stream = file.Open())
                                {
                                    bool isDebugModeEnabled = DebugAll ||
                                        pluginFileName.Equals(DebugPluginFileName, StringComparison.OrdinalIgnoreCase) &&
                                        (DebugRuleFileName == null || Path.GetFileName(file.Name).Equals(DebugRuleFileName, StringComparison.OrdinalIgnoreCase));

                                    int count = 0;
                                    using (RuleReader reader = new RuleReader(stream))
                                    {
                                        foreach (var entry in reader.ReadRules())
                                        {
                                            if (entry.Select == null && entry.Update == null && entry.Inserts.Count() == 0)
                                            {
                                                Log.Warning("Rule {0} in file {1} ignored because it lacks any operation", entry.Name, pluginFileName);
                                                continue;
                                            }

                                            var metadata = new RuleMetadata()
                                            {
                                                PluginFileName = pluginFileName,
                                                RuleFileName = Path.GetFileName(file.Name),
                                                Name = entry.Name,
                                                Description = entry.Description,
                                            };

                                            Log.Fine("Loading rule {0}\\{1}@{2}", metadata.PluginFileName, metadata.RuleFileName, metadata.Name);

                                            try
                                            {
                                                compiler.Add(entry, metadata, isDebugModeEnabled);
                                            }
                                            catch (IllegalTokenException ex)
                                            {
                                                Display.ShowProblems("Illegal Token", ex.ToString(), new Problem()
                                                {
                                                    Message = ex.Message,
                                                    File = file.GetRelativePath(),
                                                    Solution = string.Format("Please avoid using the following tokens in rule code: {0}",
                                                        string.Join(", ", RuleCompiler.GetIllegalCodeTokens()))
                                                });
                                                throw;
                                            }

                                            count++;
                                        }
                                    }
                                    Log.Fine("Loaded {0} rule(s) from file {1}", count, stream.Name);
                                }

                                progress.Update(current, total, string.Format("{0}\\{1}", pluginFileName, Path.GetFileName(file.Name)));
                            }

                            if (compiler.HasRules)
                            {
                                try
                                {
                                    compiler.CompileAll();
                                }
                                catch (CompilerException ex)
                                {
                                    StringBuilder text = new StringBuilder();
                                    List<Problem> problems = new List<Problem>();
                                    foreach (System.CodeDom.Compiler.CompilerError error in ex.Errors)
                                    {
                                        if (!error.IsWarning)
                                        {
                                            text.AppendLine(error.ToString());

                                            problems.Add(new Problem()
                                            {
                                                Message = string.Format("{0}: {1}", error.ErrorNumber, error.ErrorText),
                                                File = DataFile.GetRelativePath(error.FileName),
                                                Line = error.Line,
                                                Column = error.Column,
                                                Solution = RuleCompiler.GetCompilerErrorHint(error)
                                            });
                                        }
                                    }
                                    text.Append(ex.ToString());

                                    Display.ShowProblems("Compiler Error(s)", text.ToString(), problems.ToArray());

                                    throw ex;
                                }

                                rules.Add(pluginFileName, new List<IRule>(compiler.CompiledRules));
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error("Error occured while loading rules for plugin {0} with message: {1}", pluginFileName, ex.Message);
                            Log.Fine(ex.ToString());

                            // Depending on the kind of error, offer a choice to reload rules for this plugin
                            // Rules can be reloaded only if illegal tokens have been detected or when compilation has failed
                            ChoiceOption result = ChoiceOption.Cancel;
                            if (ex.GetType() == typeof(IllegalTokenException) || ex.GetType() == typeof(CompilerException))
                            {
                                result = Display.Choice(string.Format("Try loading rules for plugin {0} again?", pluginFileName), ChoiceOption.Yes, ChoiceOption.Continue, ChoiceOption.Cancel);
                            }
                            else
                            {
                                result = Display.Choice("Continue loading rules?", ChoiceOption.Continue, ChoiceOption.Cancel);
                            }

                            if (result == ChoiceOption.Yes)
                            {
                                Log.Info("Rules for plugin {0} will be reloaded.", pluginFileName);
                                retry = true;
                            }
                            else if (result == ChoiceOption.Continue)
                            {
                                Log.Warning("Rules for plugin {0} skipped because an error occured: {1} ", pluginFileName, ex.Message);
                            }
                            else
                            {
                                Log.Warning("Rule loading has been aborted.");
                                throw new UserAbortException("Rule loading has been aborted by the user.");
                            }
                        }
                        finally
                        {
                            Display.ClearProblems();
                        }

                    } while (retry);
                }

                current++;
            }
        }