public void GetRuleCode(List <RuleCodeCache> rules)
        {
            using (var conn = new SqlConnection(_connString))
                using (var cmd = new SqlCommand("RulesEngine.spa_GetCodeTextById", conn))
                {
                    cmd.CommandType    = CommandType.StoredProcedure;
                    cmd.CommandTimeout = 360;

                    conn.Open();

                    cmd.Parameters.Add("@CodeIds", SqlDbType.Structured).Value = rules.Select(c => c.RuleCodeId).ToDataTable("CodeIds", "Values");

                    using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                    {
                        while (reader.Read())
                        {
                            RuleCodeCache temp = rules.FirstOrDefault(c => c.RuleCodeId == int.Parse(reader["RuleCodeId"].ToString()));

                            if (temp == null)
                            {
                                continue;
                            }

                            temp.CodeHash     = (ulong)long.Parse(reader["CodeHash"].ToString());
                            temp.InputTypeId  = int.Parse(reader["InputTypeId"].ToString());
                            temp.OutputTypeId = int.Parse(reader["OutputTypeId"].ToString());
                            temp.CodeText     = reader["CodeText"].ToString();
                        }
                    }

                    conn.Close();
                }
        }
        public List <RuleCodeCache> GetRuleCodeMetaData(List <int> codeIds)
        {
            var ret = new List <RuleCodeCache>();

            using (var conn = new SqlConnection(_connString))
                using (var cmd = new SqlCommand("RulesEngine.spa_GetCodeMetaData", conn))
                {
                    cmd.CommandType    = CommandType.StoredProcedure;
                    cmd.CommandTimeout = 360;

                    conn.Open();

                    cmd.Parameters.Add("@RuleIds", SqlDbType.Structured).Value = codeIds.ToDataTable("CodeIds", "Values");

                    using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                    {
                        while (reader.Read())
                        {
                            var temp = new RuleCodeCache
                            {
                                RuleCodeId   = int.Parse(reader["RuleCodeId"].ToString()),
                                CodeHash     = (ulong)long.Parse(reader["CodeHash"].ToString()),
                                InputTypeId  = int.Parse(reader["InputTypeId"].ToString()),
                                OutputTypeId = int.Parse(reader["OutputTypeId"].ToString())
                            };

                            ret.Add(temp);
                        }
                    }

                    conn.Close();
                }

            return(ret);
        }
        private void RefreshRules()
        {
            _rules = new List <RuleAppliedBase>();
            _rules = _rulesBL.RefreshRules();

            CompilerResults results = _rulesBL.CompileRules(_rules);

            Type binaryFunction = results.CompiledAssembly.GetTypes()[0];

            foreach (RuleAppliedBase ruleAppliedBase in _rules)
            {
                //main code
                RuleCodeCache codeCache = _rulesDAL.DALCache.RuleCodes.FirstOrDefault(c => c.RuleCodeId == ruleAppliedBase.CodeId);
                if (codeCache == null)
                {
                    throw new NullReferenceException("code cache not found during delegate building");
                }

                MethodInfo r = binaryFunction.GetMethod(string.Format("Z_{0}_{1}_{2}", codeCache.CodeHash, codeCache.RuleCodeId, ruleAppliedBase.RuleAppliedId));
                if (r == null || string.IsNullOrWhiteSpace(r.Name))
                {
                    throw new NullReferenceException("method name can't be null");
                }

                var ruleRun1 = (Func <WorkflowState, bool>)Delegate.CreateDelegate(typeof(Func <WorkflowState, bool>), r);
                _codeFuncs.Add(ruleAppliedBase.CodeId, ruleRun1);

                //condition cod
                if (ruleAppliedBase.ConditionCodeId == null)
                {
                    continue;
                }
                codeCache = _rulesDAL.DALCache.RuleCodes.FirstOrDefault(c => c.RuleCodeId == ruleAppliedBase.ConditionCodeId);
                if (codeCache == null)
                {
                    throw new NullReferenceException("condCode cache not found during delegate building");
                }

                r = binaryFunction.GetMethod(string.Format("Z_{0}_{1}_", codeCache.CodeHash, codeCache.RuleCodeId));
                if (r == null || string.IsNullOrWhiteSpace(r.Name))
                {
                    throw new NullReferenceException("method name can't be null");
                }

                var ruleRun2 = (Func <WorkflowState, bool>)Delegate.CreateDelegate(typeof(Func <WorkflowState, bool>), r);
                _conditionFuncs.Add(ruleAppliedBase.ConditionCodeId.Value, ruleRun2);
            }
        }
예제 #4
0
        private void GetButton_OnClick(object sender, RoutedEventArgs e)
        {
            SetUpBL();

            if (_rulesBL != null)
            {
                RuleAppliedInstance = _rulesBL.GetBaseRuleApplied(RuleAppliedId, _ruleTableSelected);
            }

            if (RuleAppliedInstance != null)
            {
                var codeIds = new List <int> {
                    RuleAppliedInstance.CodeId
                };

                if (RuleAppliedInstance.ConditionCodeId != null)
                {
                    codeIds.Add(RuleAppliedInstance.ConditionCodeId.Value);
                }

                List <RuleCodeCache> codeMeta = RulesDAL.GetRuleCodeMetaData(codeIds);
                RulesDAL.GetRuleCode(codeMeta);

                RuleCodeCache codeCache = codeMeta.FirstOrDefault(c => c.RuleCodeId == RuleAppliedInstance.CodeId);
                if (codeCache != null)
                {
                    CodeText = codeCache.CodeText;
                }

                if (RuleAppliedInstance.ConditionCodeId != null)
                {
                    RuleCodeCache condCodeCache = codeMeta.FirstOrDefault(c => c.RuleCodeId == RuleAppliedInstance.ConditionCodeId.Value);
                    if (condCodeCache != null)
                    {
                        CodeConditionText = condCodeCache.CodeText;
                    }
                }
            }

            GUILogging.LogMessage(RuleAppliedInstance != null
                ? string.Format("RuleApplied {0} found", RuleAppliedInstance.RuleAppliedId)
                : string.Format("RuleApplied {0} not found", RuleAppliedId));
        }
예제 #5
0
        private void WriteRuleCodeToStream(TextWriter tw, RuleCodeCache codeCache, int?ruleAppliedId)
        {
            var methodName = string.Format("Z_{0}_{1}_{2}", codeCache.CodeHash, codeCache.RuleCodeId, ruleAppliedId);

            ////public static outputtype methodName(inputtype input){
            //// ruleCode }
            ////
            tw.Write("public static ");

            RuleCodeIOType outputType = _rulesDAL.DALCache.RuleCodeIOTypes.FirstOrDefault(c => c.RuleCodeIOTypeId == codeCache.OutputTypeId);

            if (outputType == null)
            {
                throw new KeyNotFoundException("Output type not found in the cache");
            }

            tw.Write(outputType.TypeName);

            tw.Write(" ");
            tw.Write(methodName);
            tw.Write("( ");

            RuleCodeIOType inputType = _rulesDAL.DALCache.RuleCodeIOTypes.FirstOrDefault(c => c.RuleCodeIOTypeId == codeCache.InputTypeId);

            if (inputType == null)
            {
                throw new KeyNotFoundException("Input Type not found in the cache");
            }

            tw.Write(inputType.TypeName);

            tw.Write(" obj)");
            tw.WriteLine("{");

            if (codeCache.CodeText == null)
            {
                throw new NullReferenceException("can't have null code in CompileRules");
            }

            tw.WriteLine(codeCache.CodeText);

            tw.WriteLine("}");
        }
예제 #6
0
        //private List<RuleCacheRefresh> GetRuleInfoFromFile(string filename, ref List<RuleAppliedBase> rules)
        private List <RuleCacheRefresh> GetRuleInfoFromFile(string filename)
        {
            ////sample
            //public static
            //ZirMed.Claims.Objects.Transactions.IClaim Z_1_4_6(ZirMed.Claims.Objects.Transactions.IClaim input)
            //{
            //    throw new System.Exception();
            //}

            var refreshResults = new List <RuleCacheRefresh>();

            var currentLine = 0;

            using (TextReader tr = new StreamReader(new FileStream(filename, FileMode.OpenOrCreate)))
            {
                var line = tr.ReadLine();

                var insideClass  = false;
                var insideMethod = false;

                var bracketCount    = 0;
                var methodStartLine = 0;

                while (line != null)
                {
                    currentLine++;
                    bracketCount += line.Split('{').Length - 1;
                    bracketCount -= line.Split('}').Length - 1;

                    if (bracketCount < 2)
                    {
                        insideClass = false;
                    }
                    if (bracketCount < 3)
                    {
                        if (insideMethod && methodStartLine > 0)
                        {
                            RuleCacheRefresh foundMethodCache = refreshResults.FirstOrDefault(c => c.StartLineNumber == methodStartLine);

                            if (foundMethodCache == null)
                            {
                                throw new NullReferenceException("srsly, why is this null, we just found the method name and marked it a few lines ago");
                            }

                            foundMethodCache.EndLineNumber = currentLine;
                        }

                        methodStartLine = 0;
                        insideMethod    = false;
                    }

                    if (line.Contains("public static class"))
                    {
                        insideClass = true;
                        line        = tr.ReadLine();
                        continue;
                    }

                    if (!insideClass)
                    {
                        line = tr.ReadLine();
                        continue;
                    }

                    if (line.Contains("public static") && !insideMethod)
                    {
                        insideMethod = true;

                        string[] splitMethodName = line.Split(new[] { ' ' }, StringSplitOptions.None);

                        if (splitMethodName.Any())
                        {
                            var      methodName      = splitMethodName[3];
                            string[] methodNameSplit = methodName.Split(new[] { '_' }, StringSplitOptions.None);
                            methodNameSplit[methodNameSplit.Length - 1] =
                                methodNameSplit[methodNameSplit.Length - 1].Substring(0, methodNameSplit[methodNameSplit.Length - 1].Length - 1);

                            if (methodNameSplit.Any())
                            {
                                var temp = new RuleCacheRefresh
                                {
                                    CodeHash = ulong.Parse(methodNameSplit[1]),
                                    CodeId   = int.Parse(methodNameSplit[2])
                                };

                                if (methodNameSplit.Length > 3 && !string.IsNullOrWhiteSpace(methodNameSplit[3]))
                                {
                                    temp.RuleAppliedId = int.Parse(methodNameSplit[3]);
                                }

                                RuleCodeCache tempCode = _rulesDAL.DALCache.RuleCodes.FirstOrDefault(c => c.RuleCodeId == temp.CodeId);

                                if (tempCode != null)
                                {
                                    tempCode.ExistsInCache = true;
                                    if (tempCode.CodeHash != temp.CodeHash)
                                    {
                                        temp.StartLineNumber = methodStartLine = currentLine;
                                        refreshResults.Add(temp);
                                    }
                                    else
                                    {
                                        tempCode.NeedsRefresh = false;
                                    }
                                }
                            }
                        }
                    }

                    line = tr.ReadLine();
                }
            }

            return(refreshResults);
        }
예제 #7
0
        public CompilerResults CompileRules(List <RuleAppliedBase> rules)
        {
            if (!rules.Any())
            {
                return(null);
            }

            List <int> rulesToPull = rules.Select(c => c.CodeId).ToList();

            rulesToPull.AddRange(rules.Where(c => c.ConditionCodeId != null).Select(c => (int)c.ConditionCodeId).ToList());

            _rulesDAL.DALCache.RefreshRuleCodes(rulesToPull, true);

            string catName = "", subCatName = "";

            RuleCategory a = _rulesDAL.DALCache.RuleCategories.FirstOrDefault(c =>
            {
                RuleAppliedBase ruleAppliedBase = rules.FirstOrDefault();
                return(ruleAppliedBase != null && c.RuleCategoryId == ruleAppliedBase.RuleCategoryId);
            });

            if (a != null)
            {
                catName = a.CategoryName;
            }

            RuleCategory b = _rulesDAL.DALCache.RuleCategories.FirstOrDefault(c =>
            {
                RuleAppliedBase ruleAppliedBase = rules.FirstOrDefault();
                return(ruleAppliedBase != null && c.RuleCategoryId == ruleAppliedBase.RuleSubCategoryId);
            });

            if (b != null)
            {
                subCatName = b.CategoryName;
            }

            var tempFileName = Guid.NewGuid().ToString();
            var realFileName = catName + "_" + subCatName + ".cs";

            var codeFileExists = false;
            var linesToRemove  = new List <RuleCacheRefresh>();

            //if the file already exists, we need to read through and get info on the what code was written out
            //we also need to copy over all code that has the same method signature into a new temp file
            //afterwards, we will insert the new/altered code at the end of the temp file and swap them out.
            if (File.Exists(realFileName))
            {
                linesToRemove = GetRuleInfoFromFile(realFileName);

                using (FileStream realFs = File.OpenRead(realFileName))
                    using (FileStream tempFs = File.Create(tempFileName))
                    {
                        PrepFile(realFs, tempFs, linesToRemove);
                    }

                codeFileExists = true;
            }

            _rulesDAL.GetRuleCode(_rulesDAL.DALCache.RuleCodes.Where(c => c.NeedsRefresh || !c.ExistsInCache).ToList());

            using (TextWriter tw = new StreamWriter(tempFileName, codeFileExists))
            {
                if (codeFileExists)
                {
                    foreach (RuleCacheRefresh ruleRemoved in linesToRemove)
                    {
                        RuleCodeCache code =
                            _rulesDAL.DALCache.RuleCodes.FirstOrDefault(d => d.RuleCodeId == ruleRemoved.CodeId);

                        if (code == null)
                        {
                            throw new NullReferenceException("code not found");
                        }

                        int?tempRuleAppId = null;

                        if (ruleRemoved.RuleAppliedId > 0)
                        {
                            tempRuleAppId = ruleRemoved.RuleAppliedId;
                        }

                        WriteRuleCodeToStream(tw, code, tempRuleAppId);
                    }
                }
                else
                {
                    tw.WriteLine(
                        "using System.Linq; using System.Collections; using System.Collections.Generic; namespace LawsonCS.RulesEngine { ");
                    //example
                    //public static class Validator_PostEnrollment
                    tw.WriteLine(" public static class " + catName + "_" + subCatName + "{");

                    foreach (RuleAppliedBase rule in rules)
                    {
                        RuleCodeCache code =
                            _rulesDAL.DALCache.RuleCodes.FirstOrDefault(d => d.RuleCodeId == rule.CodeId);

                        if (code == null)
                        {
                            throw new NullReferenceException("code not found");
                        }

                        //we only want to write the rule out if it is marked as needsRefresh
                        RuleCodeCache foundRuleCacheCheck =
                            _rulesDAL.DALCache.RuleCodes.FirstOrDefault(c => c.RuleCodeId == rule.CodeId);

                        if (foundRuleCacheCheck != null && foundRuleCacheCheck.NeedsRefresh)
                        {
                            WriteRuleCodeToStream(tw, code, rule.RuleAppliedId);
                        }
                    }

                    foreach (RuleAppliedBase ruleCond in rules.Where(c => c.ConditionCodeId != null))
                    {
                        if (ruleCond.ConditionCodeId == null)
                        {
                            continue;
                        }

                        RuleCodeCache code =
                            _rulesDAL.DALCache.RuleCodes.FirstOrDefault(
                                d => d.RuleCodeId == ruleCond.ConditionCodeId.Value);

                        if (code == null)
                        {
                            throw new NullReferenceException("code not found");
                        }

                        //we only want to write the rule out if it is marked as needsRefresh
                        RuleCodeCache foundRuleCacheCheck =
                            _rulesDAL.DALCache.RuleCodes.FirstOrDefault(c => c.RuleCodeId == ruleCond.CodeId);

                        if (foundRuleCacheCheck != null && foundRuleCacheCheck.NeedsRefresh)
                        {
                            WriteRuleCodeToStream(tw, code, null);
                        }
                    }
                }

                foreach (var s in _codeFooter)
                {
                    tw.WriteLine(s);
                }

                tw.Flush();
            }

            foreach (RuleCodeCache ruleCodeCache in _rulesDAL.DALCache.RuleCodes)
            {
                ruleCodeCache.CodeText     = null;
                ruleCodeCache.NeedsRefresh = false;
            }

            File.Copy(tempFileName, realFileName, true);
            File.Copy(tempFileName, ConfigurationManager.AppSettings["NonStandardLogLocation"] + "\\" + DateTime.Now.ToString("yy-MM-dd@HH mm ss") + "_" + realFileName, true);

            File.Delete(tempFileName);
            File.Delete(_ruleTable + ".dll");

            var compilerparams = new CompilerParameters()
            {
                GenerateExecutable      = false,
                GenerateInMemory        = false,
                IncludeDebugInformation = false,
                TreatWarningsAsErrors   = false,
                CompilerOptions         = string.Format("/lib:{0}", AppDomain.CurrentDomain.BaseDirectory),
                OutputAssembly          = _ruleTable + ".dll",
            };

            List <string> fileList = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory).Where(c => c.Substring(c.Length - 3) == "dll").ToList();

            compilerparams.ReferencedAssemblies.AddRange(fileList.ToArray());
            compilerparams.ReferencedAssemblies.AddRange(Directory.GetFiles(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5").Where(c => c.EndsWith(".dll") && !c.EndsWith("mscorlib.dll")).ToArray());

            CompilerResults results = CodeDomProvider.CreateProvider("CSharp").CompileAssemblyFromFile(compilerparams, realFileName);

            if (results.Errors.HasErrors)
            {
                throw new Exception(results.Errors[0].ErrorText);
            }

            return(results);
        }