/// <summary>
        /// Preprocess document for compilation.
        /// </summary>
        /// <param name="req">compile request</param>
        /// <param name="kentity">language for project</param>
        /// <param name="filePath">file path</param>
        /// <param name="document">document to compile</param>
        /// <param name="nfUXErrors">list of errors</param>
        /// <param name="rootUrl">root url</param>
        public static void PreprocessDocument(CompileResourceRequest req, KEntity kentity, string filePath, out HtmlDocument document, List <CompilerError> nfUXErrors, out string rootUrl)
        {
            document = GetDocumentObject();
            try
            {
                document.LoadHtml(req.FileContent);
            }
            catch { }

            rootUrl = "";

            /*
             * if (document.ParseErrors.Count() > 0)
             * {
             *  foreach (var error in document.ParseErrors.ToList())
             *  {
             *      nfUXErrors.Add(CompileResultHelper.GetCompileError(error.Reason, error.Line, error.LinePosition));
             *  }
             * }
             */
            var descendants = document.DocumentNode.Descendants();

            PrepCommentTagsForCompile(ref document, ref descendants);
            SetPageProperties(req, kentity, filePath, ref rootUrl, descendants);
        }
        public dynamic EvaluateExpression(Node tree, KEntity entity, Models.Pagination viewDetails, Dictionary <string, AliasReference> classNameAlias, dynamic businessData, dynamic kresult, string queryString, out bool hasData, Dictionary <string, long> functionLog, bool isDetailsView = false, bool isNFSite = false, string developerId = null)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            try
            {
                string baseClassName = entity.Classes.Where(c => c.ClassType == KClassType.BaseClass).FirstOrDefault().Name;
                ReplaceExpressionsInTreeAsync(tree, baseClassName, viewDetails, classNameAlias, businessData, entity, kresult, queryString, isDetailsView, isNFSite, developerId);
                Token result = ParseTress.Parse(tree);
                if (result?.Type == null)
                {
                    hasData = false;
                }
                else
                {
                    hasData = result.Type != TOKENTYPE.NoData;
                }
                return(result?.Value ?? "");
            }
            catch (Exception ex) { throw; }
            finally
            {
                stopwatch.Stop();
                Helper.UpdateFunctionLog(functionLog, String.Format(Constant.EVALUATE_EXPRESSION, "Tree"), stopwatch.ElapsedMilliseconds);
            }
        }
Example #3
0
        public static CompilerError ValidateView(ref string expression, KEntity kentity)
        {
            var pageClassResult = Helper.Constants.ViewClassRegularExpression.Matches(expression);

            if (pageClassResult != null && pageClassResult.Count > 0)
            {
                foreach (var page in pageClassResult.ToList())
                {
                    var groupparam = page.Groups[2].Value?.Trim('(', ')');
                    if (!string.IsNullOrEmpty(groupparam))
                    {
                        var partialViewParams = groupparam.Split(',');
                        var viewName          = partialViewParams[0]?.Trim('\'');

                        if (kentity.Classes.Any(x => x.ClassType == KClassType.BaseClass && x.Description != null && x.Description.ToLower() == viewName.ToLower() && x.Name != null))
                        {
                            expression = expression.Replace(page.Groups[1].Value, kentity.Classes.First(x => x.ClassType == KClassType.BaseClass && x.Description != null && x.Description.ToLower() == viewName.ToLower() && x.Name != null).Name);
                        }
                        else
                        {
                            return(CompileResultHelper.GetCompileError(string.Format(ErrorCodeConstants.UnrecognizedView, viewName)));
                        }
                    }
                }
            }
            return(null);
        }
        internal static KEntity ParseToKEntity(dynamic jsonObject)
        {
            try
            {
                if (jsonObject != null)
                {
                    var completejson = jsonObject;
                    var finalJson    = new KEntity();
                    var classes      = jsonObject["Classes"];
                    var classesList  = new List <KClass>();
                    foreach (var tempClass in classes)
                    {
                        var parentClass = tempClass;

                        if (tempClass["ClassType"].Value.ToString().Equals("1"))
                        {
                            finalJson.EntityName = tempClass["Name"].Value;
                        }


                        var parentKClass = childClasses(tempClass, classesList);
                        classesList.Add(parentKClass);
                    }

                    finalJson.Classes = classesList;

                    return(finalJson);
                }
            }
            catch (Exception ex)
            {
            }

            return(null);
        }
        internal KProperty GetProperty(string expression, KEntity entity)
        {
            KProperty kProperty = null;
            KClass    kClass    = null;

            string[] classHierarchyList = expression.Split('.');
            if (entity != null)
            {
                kClass = entity.Classes.Where(x => x.ClassType == KClassType.BaseClass && x.Name.ToLower() == classHierarchyList[0].ToLower()).FirstOrDefault();
                if (kClass == null)
                {
                    return(null);
                }
                for (int i = 1; i < classHierarchyList.Length - 1; i++)
                {
                    string    propName = classHierarchyList[i].Split('[')[0];
                    KProperty prop     = kClass.PropertyList.Where(x => x.Name.ToLower() == propName.ToLower()).FirstOrDefault();
                    if (prop == null)
                    {
                        return(null);
                    }
                    kClass = entity.Classes.Where(x => x.Name.ToLower() == prop.DataType.Name.ToLower()).FirstOrDefault();
                    if (kClass == null)
                    {
                        return(null);
                    }
                }
                string finalPropName = classHierarchyList[classHierarchyList.Length - 1].Split('[')[0].ToLower();
                kProperty = kClass.PropertyList.Where(x => x.Name == finalPropName).FirstOrDefault();
            }
            return(kProperty);
        }
        /// <summary>
        /// Set properties like pageType, IsStatic, rootUrl, URLPattern.
        /// </summary>
        /// <param name="req">compile request</param>
        /// <param name="kentity">k language for project</param>
        /// <param name="filePath">file path</param>
        /// <param name="rootUrl">root url for project</param>
        /// <param name="descendants">descendants of the document to compile</param>
        private static void SetPageProperties(CompileResourceRequest req, KEntity kentity, string filePath, ref string rootUrl, IEnumerable <HtmlNode> descendants)
        {
            //If the page is set to static, don't validate against language
            if (descendants.Any(x => x.Attributes[LanguageAttributes.KPartial.GetDescription()] != null))
            {
                req.PageType = Models.Project.KitsunePageType.PARTIAL;
            }
            //If the page is partial then by default its dynamic
            if (req.PageType == Models.Project.KitsunePageType.PARTIAL)
            {
                req.IsStatic = false;
            }
            else
            {
                req.IsStatic = IsResourceStatic(req.FileContent, req.SourcePath);
            }

            if (!req.IsStatic)
            {
                //Generate valid class name from the page name
                req.ClassName = GenerateClassName(filePath);
                rootUrl       = string.Format("{0}.rootaliasurl.url", kentity?.EntityName?.ToLower() ?? Constants.KPayDefaultSchema.ToLower());
                if (string.IsNullOrEmpty(req.UrlPattern))
                {
                    req.UrlPattern = string.Format("[[{0}]]/{1}", rootUrl, filePath.ToLower());
                }
            }
        }
Example #7
0
        public List <ObjectReference> BuildMetaClass(KEntity entity, List <MultiplePositionProperty> PropertyNames, string SourcePath)
        {
            try
            {
                metaClass        = new List <ObjectReference>();
                metaPropertyList = new MetaPropertyType();
                var baseClasses = entity.Classes.Where(x => x.ClassType == KClassType.BaseClass);
                //var userDefinedClasses = entity.Classes.Where(x => x.ClassType == KClassType.UserDefinedClass);
                //var defaultClassses = entity.Classes.Where(x => x.ClassType == KClassType.DefaultClass);
                //var dataTypeClassses = entity.Classes.Where(x => x.ClassType == KClassType.DefaultClass);
                var prop       = PropertyNames.Select(x => x.Property.ToLower().Replace("-1", "")).ToList(); //changing all porperties to lower case and removing -1 thats been signifying whole array to fetch
                var jsonObject = new ExpandoObject();
                var dictionary = (IDictionary <string, object>)jsonObject;

                foreach (var property in prop)
                {
                    var objectPathArray = property.ToLower().Split('.');
                    if (!metaClass.Any(x => x.name == objectPathArray[0]))
                    {
                        metaClass.Add(new ObjectReference
                        {
                            name       = objectPathArray[0],
                            type       = metaPropertyType.obj,
                            properties = new List <ObjectReference>()
                        });
                    }
                    if (objectPathArray.Length > 1)
                    {
                        var ind = 0;
                        var basePropertyName = objectPathArray[ind];
                        var baseClass        = baseClasses.FirstOrDefault(x => x.Name?.ToLower() == basePropertyName);

                        if (baseClass != null)
                        {
                            metaPropertyList = new MetaPropertyType
                            {
                                Property = property,
                                Type     = new List <MetaPartPropertyType>()
                                {
                                    new MetaPartPropertyType {
                                        Type = metaPropertyType.obj
                                    }
                                }
                            };
                            var objectPathArrayCopy = new string[objectPathArray.Length];
                            objectPathArray.CopyTo(objectPathArrayCopy, 0);
                            FindDataType(objectPathArrayCopy, 1, basePropertyName, PropertyType.obj, entity);
                            var result = CreatePartMetaClass(objectPathArray, ++ind, metaClass.FirstOrDefault(x => x.name == objectPathArray[0]).properties);
                        }
                    }
                }
                return(metaClass);
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Failed to Generate meta Class for {0}: {1}", SourcePath, ex.Message));
            }
        }
Example #8
0
        private static void UpdateForPublish(ref HtmlDocument document,
                                             CompileResourceRequest request,
                                             KEntity kentity,
                                             List <CompilerError> compileErrors,
                                             Dictionary <string, int> customVariables,
                                             GetProjectDetailsResponseModel projectDetails,
                                             GetPartialPagesDetailsResponseModel partialPages = null,
                                             List <KLanguageModel> componentEntities          = null,
                                             bool isCSRFPresent = false
                                             )
        {
            var htmlString = document.DocumentNode.OuterHtml.ToString();

            htmlString = htmlString.Replace("itemscope=\"\"", "itemscope");
            if (!string.IsNullOrEmpty(htmlString))
            {
                if (isCSRFPresent)
                {
                    htmlString = Constants.CSRFRegularExpression.Replace(htmlString, Constants.CSRFReplacementToken);
                }

                var lines = htmlString.Split('\n');

                var descendants = document.DocumentNode.Descendants();
                var kdlOb       = descendants.Where(s => s.Attributes[LanguageAttributes.KDL.GetDescription()] != null);
                //store temporary original KDL value before replacement of _system object
                var tempKDL = string.Empty;
                if (kdlOb != null && kdlOb.Any())
                {
                    tempKDL = kdlOb.FirstOrDefault().GetAttributeValue(LanguageAttributes.KDL.GetDescription(), null);
                }

                for (int i = 0; i < lines.Length; i++)
                {
                    ReplaceCustomVariables(customVariables, lines, i);
                    InjectPartialView(request, kentity, projectDetails, partialPages, lines, i);
                    ReplaceComponentEntities(projectDetails, componentEntities, lines, i);
                    SetObject(compileErrors, kentity, projectDetails, lines, i, request.ClassName);
                }
                htmlString = string.Join("\n", lines);
                document   = GetDocumentObject();
                document.LoadHtml(htmlString);

                //restore back the original k-dl attribute
                if (!string.IsNullOrEmpty(tempKDL))
                {
                    document.DocumentNode.Descendants().First(x => x.Attributes["k-dl"] != null).Attributes["k-dl"].Value = tempKDL;
                }
                htmlString = document.DocumentNode.OuterHtml;
            }
        }
Example #9
0
        public static bool IsSearchableProperty(string propertyPath, KEntity entity, out KClass kClass)
        {
            kClass = null;
            var objectPathArray = propertyPath.ToLower().Split('.');

            if (objectPathArray.Length > 1)
            {
                var obClass         = new KClass();
                var obProperty      = new KProperty();
                var dataTypeClasses = Kitsune.Helper.Constants.DataTypeClasses;
                for (var i = 0; i < objectPathArray.Length; i++)
                {
                    if (i == 0)
                    {
                        obClass = entity.Classes.FirstOrDefault(x => x.ClassType == KClassType.BaseClass && x.Name == objectPathArray[i]);
                        if (obClass == null)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        obProperty = obClass.PropertyList.FirstOrDefault(x => x.Name.ToLower() == objectPathArray[i]);
                        if (obProperty == null)
                        {
                            return(false);
                        }
                        else if ((obProperty.Type == PropertyType.array && !dataTypeClasses.Contains(obProperty.DataType?.Name?.ToLower())) || obProperty.Type == PropertyType.obj)
                        {
                            obClass = entity.Classes.FirstOrDefault(x => x.ClassType == KClassType.UserDefinedClass && x.Name?.ToLower() == obProperty.DataType?.Name?.ToLower());
                        }
                        else
                        {
                            return(false);
                        }
                    }
                }
                if (obClass != null)
                {
                    kClass = obClass;
                    if (obProperty != null && obProperty.Type == PropertyType.array)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Example #10
0
        private static void HandleScriptInjection(HtmlDocument document,
                                                  CompileResourceRequest request,
                                                  KEntity kentity,
                                                  string rootUrl,
                                                  GetProjectDetailsResponseModel projectDetails, bool isCSRF)
        {
            HtmlNode body        = document.DocumentNode.SelectSingleNode("//body");
            var      descendants = document.DocumentNode.Descendants();
            var      kPayObject  = descendants.Where(s => s.Attributes[LanguageAttributes.KPayAmount.GetDescription()] != null);


            if (body != null)
            {
                if (kPayObject != null && kPayObject.Any())
                {
                    HtmlNode kPayScript = document.CreateElement("script");
                    kPayScript.SetAttributeValue("src", Constants.KPayJsLink);
                    kPayScript.SetAttributeValue("type", "text/javascript");
                    kPayScript.SetAttributeValue("charset", "utf-8");
                    kPayScript.SetAttributeValue("defer", "defer");
                    kPayScript.SetAttributeValue("async", "async");
                    body.AppendChild(kPayScript);
                }

                if (isCSRF)
                {
                    HtmlNode csrfScript = document.CreateElement("script");
                    csrfScript.SetAttributeValue("src", Constants.CSRFTokenJSLink);
                    csrfScript.SetAttributeValue("type", "text/javascript");
                    csrfScript.SetAttributeValue("charset", "utf-8");
                    csrfScript.SetAttributeValue("defer", "defer");
                    csrfScript.SetAttributeValue("async", "async");
                    body.AppendChild(csrfScript);
                }

                HtmlNode ThemeIdWidget = HtmlNode.CreateNode(string.Format("<span style='display: none;' id='GET-VALUE(THEME-ID)'>{0}</span>", request.ProjectId));
                HtmlNode WebsiteId     = HtmlNode.CreateNode("<span style='display: none;' id='GET-VALUE(WEBSITE-ID)'>[KITSUNE_WEBSITE_ID]</span>");
                body.AppendChild(ThemeIdWidget);
                body.AppendChild(WebsiteId);

                if (kentity.EntityName != Constants.KPayDefaultSchema)
                {
                    HtmlNode RootAlias = HtmlNode.CreateNode(string.Format("<a style='display: none;' href='[[{0}]]' id='GET-URL(HOME)'></a>", rootUrl));
                    body.AppendChild(RootAlias);
                }
            }
        }
Example #11
0
        internal KProperty GetProperty(List <CompilerError> compileErrors, HtmlAttribute dynamicAttribute, DocumentValidator documentValidator, string referenceObject, Dictionary <string, string> classNameAlias)
        {
            KProperty kProperty      = null;
            KClass    kClass         = null;
            string    expression     = referenceObject;
            string    baseExpression = expression.Split('.')[0].Split('[')[0].ToLower();

            while (baseExpression != "kresult" && baseExpression != "search" && classNameAlias.ContainsKey(baseExpression))
            {
                string[] expressionParts = expression.Split('.');
                expressionParts[0] = classNameAlias[baseExpression];
                expression         = String.Join(".", expressionParts);
                baseExpression     = expression.Split('.')[0].Split('[')[0].ToLower();
            }
            string[] classHierarchyList = expression.Split('.');
            KEntity  entity             = documentValidator?.GetKEntityFromEntityName(classHierarchyList[0]) ?? documentValidator?.GetKEntityFromEntityName(documentValidator.defaultEntity);

            if (entity != null)
            {
                kClass = entity.Classes.Where(x => x.ClassType == KClassType.BaseClass && x.Name.ToLower() == classHierarchyList[0].ToLower()).FirstOrDefault();
                if (kClass == null)
                {
                    compileErrors.Add(CompileResultHelper.GetCompileError(String.Format(ErrorCodeConstants.UnrecognizedType, classHierarchyList[0]), dynamicAttribute.Line, dynamicAttribute.LinePosition));
                    return(null);
                }
                for (int i = 1; i < classHierarchyList.Length - 1; i++)
                {
                    string    propName = classHierarchyList[i].Split('[')[0];
                    KProperty prop     = kClass.PropertyList.Where(x => x.Name.ToLower() == propName.ToLower()).FirstOrDefault();
                    if (prop == null)
                    {
                        compileErrors.Add(CompileResultHelper.GetCompileError(String.Format(ErrorCodeConstants.UnrecognizedProperty, propName), dynamicAttribute.Line, dynamicAttribute.LinePosition));
                        return(null);
                    }
                    kClass = entity.Classes.Where(x => x.Name.ToLower() == prop.DataType.Name.ToLower()).FirstOrDefault();
                    if (kClass == null)
                    {
                        compileErrors.Add(CompileResultHelper.GetCompileError(String.Format(ErrorCodeConstants.UnrecognizedType, prop.DataType.Name), dynamicAttribute.Line, dynamicAttribute.LinePosition));
                        return(null);
                    }
                }
                string finalPropName = classHierarchyList[classHierarchyList.Length - 1].Split('[')[0].ToLower();
                kProperty = kClass.PropertyList.Where(x => x.Name == finalPropName && x.Type == PropertyType.array).FirstOrDefault();
            }
            return(kProperty);
        }
Example #12
0
        private static void InjectPartialView(CompileResourceRequest request, KEntity kentity, GetProjectDetailsResponseModel projectDetails, GetPartialPagesDetailsResponseModel partialPages, string[] lines, int i)
        {
            var partialregex  = Constants.PartialPageRegularExpression;
            var partialresult = partialregex.Matches(lines[i]);

            if (partialPages != null && partialPages.Resources != null && partialPages.Resources.Any())
            {
                for (int mc = 0; mc < partialresult.Count; mc++)
                {
                    if (partialresult[mc].Groups.Count > 1)
                    {
                        var groupparam = partialresult[mc].Groups[1].Value?.Trim('(', ')').Trim('\'').ToLower();
                        if (!string.IsNullOrEmpty(groupparam))
                        {
                            var partialViewParams = groupparam.Split(',');
                            var viewName          = partialViewParams[0]?.Trim('\'');

                            if (projectDetails.Resources.Any(x => x.PageType == Models.Project.KitsunePageType.PARTIAL && x.SourcePath.ToLower() == viewName.ToLower()))
                            {
                                var htmlData = new HtmlDocument();
                                htmlData.LoadHtml(partialPages.Resources.FirstOrDefault(x => string.Compare(x.SourcePath, viewName, true) == 0).HtmlSourceString);
                                //Support partial page with Html body and without body tag
                                string partialbody       = htmlData.DocumentNode.SelectSingleNode("/html/body")?.InnerHtml ?? htmlData.DocumentNode.OuterHtml;
                                var    partialCompiledOb = KitsuneCompiler.CompileHTML(new CompileResourceRequest
                                {
                                    FileContent = partialbody,
                                    IsPublish   = true,
                                    SourcePath  = viewName,
                                    PageType    = Models.Project.KitsunePageType.PARTIAL,
                                    ProjectId   = request.ProjectId,
                                    UserEmail   = request.UserEmail
                                }, out htmlData, projectDetails, kentity, partialPages);
                                if (partialCompiledOb != null && partialCompiledOb.Success)
                                {
                                    lines[i] = lines[i].Replace(partialresult[mc].Value, partialCompiledOb.CompiledString);
                                }
                            }
                        }
                    }
                }
            }
        }
        private dynamic GetDefaultProperty(KEntity entity, string fullExpression)
        {
            KProperty property = GetProperty(fullExpression, entity);

            switch (property.Type)
            {
            case PropertyType.str:
                return("");

            case PropertyType.number:
                return(0);

            case PropertyType.boolean:
                return(false);

            case PropertyType.kstring:
                return("");
            }
            return(null);
        }
        internal static void SaveEntityInfo(string key, KEntity entityModel)
        {
            try
            {
                if (!String.IsNullOrEmpty(key) && isApiCacheEnabled)
                {
                    key = key.ToUpper();

                    var cacheObject = JsonConvert.SerializeObject(entityModel);

                    var task = ApiCacheService.Save(key, cacheObject);
                    if (!task.Wait(_cacheTimeout))
                    {
                        ConsoleLogger.Write($"ERROR: CACHE SaveEntityInfo - Redis TimeOut");
                    }
                }
            }
            catch (Exception ex)
            {
                ConsoleLogger.Write($"ERROR: CACHE SaveEntityInfo - {ex.ToString()}");
            }
        }
        public BlockLevelKLMExecutor(KEntity entity, Dictionary <string, long> functionLog, KitsunePage page, Pagination viewDetail, string rootAliasUri, string websiteId, string schemaId, string url, string urlPattern, string urlPatternRegex, dynamic websiteData, string fptag, bool enableSrcSet = true, string developerId = null)
        {
            this.entity      = entity;
            this.functionLog = functionLog;
            this.url         = url ?? "";
            if (urlPattern != null)
            {
                this.urlPattern = urlPattern.Substring(urlPattern.IndexOf("/") + 1);
            }
            else
            {
                this.urlPattern = urlPattern ?? "";
            }
            this.urlPatternRegex = urlPatternRegex?.Replace("a-zA-Z0-9", @"a-zA-Z0-9\(\)_\[\]") ?? "";
            this.page            = page;
            this.rootAliasUri    = rootAliasUri ?? "";
            this.viewDetail      = viewDetail;
            this.developerId     = developerId;
            this.websiteId       = websiteId;
            baseClassName        = entity?.Classes?.Where(c => c.ClassType == KClassType.BaseClass)?.FirstOrDefault().Name;

            evaluator = new BlockLevelExpressionEvaluator(entity, viewDetail, functionLog, websiteId, schemaId, websiteData, rootAliasUri, fptag, enableSrcSet, developerId);
        }
Example #16
0
        /// <summary>
        /// Process nodes with KDL tag.
        /// </summary>
        /// <param name="request">Incoming request</param>
        /// <param name="compileErrors">list of errors during compilation</param>
        /// <param name="kentity">project language</param>
        /// <param name="customVariables">output list to hold custom variables</param>
        /// <param name="rootUrl">root url</param>
        /// <param name="filePath">file path</param>
        /// <param name="classNameAlias">aliases used either with k-repeat or k-object</param>
        /// <param name="classNameAliasdepth">depth based storage of aliases</param>
        /// <param name="depth">depth of the node in DOM</param>
        /// <param name="dynamicAttribute">key-value pair of the k-tag</param>
        public override void ProcessNode(CompileResourceRequest request, List <CompilerError> compileErrors, Dictionary <string, int> customVariables, string rootUrl, string filePath, Dictionary <string, string> classNameAlias, Dictionary <int, string> classNameAliasdepth, int depth, HtmlNode node, HtmlAttribute dynamicAttribute, List <MatchNode> objectNamesToValidate, DocumentValidator documentValidator)
        {
            var pattern = dynamicAttribute.Value;

            if (!string.IsNullOrWhiteSpace(pattern))
            {
                pattern = pattern.Trim().Trim('/');
                if (pattern.IndexOf("currentpagenumber.urlencode()") < 0)
                {
                    pattern = pattern.Replace("currentpagenumber", "currentpagenumber.urlencode()");
                }

                KEntity kentity = documentValidator.GetKEntityFromEntityName(documentValidator.defaultEntity);

                #region Validate unique id exist for detailspage
                if (request.PageType == Models.Project.KitsunePageType.DETAILS)
                {
                    //added support for multiple kobjects, check for the last objetcts unique param
                    var kobjects   = request.KObject.Split(':')[0].Split(',');
                    var kobjParam  = kobjects[kobjects.Length - 1].ToLower();
                    var kidRegex   = Kitsune.Helper.Constants.GetKObjectIteratorRegex($"{kobjParam}._kid");
                    var _idRegex   = Kitsune.Helper.Constants.GetKObjectIteratorRegex($"{kobjParam}._id");
                    var indexRegex = Kitsune.Helper.Constants.GetKObjectIteratorRegex($"{kobjParam}.index");
                    var idRegex    = Kitsune.Helper.Constants.GetKObjectIteratorRegex($"{kobjParam}.id");
                    if (!(_idRegex.IsMatch(pattern.ToLower()) || kidRegex.IsMatch(pattern.ToLower()) || indexRegex.IsMatch(pattern.ToLower()) || idRegex.IsMatch(pattern.ToLower())))
                    {
                        compileErrors.Add(new CompilerError()
                        {
                            LineNumber   = dynamicAttribute.Line,
                            LinePosition = dynamicAttribute.LinePosition,
                            Message      = string.Format(ErrorCodeConstants.MissingUniqueIndexForDetailsPage, request.KObject.Split(':').Length > 1 ? request.KObject.Split(':')[1] : kobjParam)
                        });
                    }
                }
                #endregion

                var viewExist = KitsuneCompiler.ValidateView(ref pattern, kentity);
                if (viewExist != null)
                {
                    viewExist.LineNumber   = dynamicAttribute.Line;
                    viewExist.LinePosition = dynamicAttribute.LinePosition;
                    compileErrors.Add(viewExist);
                }
                var pagination = Kitsune.Helper.Constants.PaginationRegularExpression.Match(pattern);

                if (pagination != null && pagination.Success)
                {
                    var matches = Kitsune.Helper.Constants.FunctionParameterExpression.Match(pagination.Value);
                    if (matches != null && matches.Groups?.Count > 0)
                    {
                        request.UrlPattern = string.Format("[[{0}]]/{1}-[[{2}.currentpagenumber]]", rootUrl, matches.Groups[1].Value.Substring(matches.Groups[1].Value.IndexOf('.') + 1), request.ClassName);
                    }
                }
                else
                {
                    var expressions = Helper.HtmlHelper.GetExpressionFromElement(pattern, 0);
                    //Add urlencode
                    if (expressions != null && expressions.Any())
                    {
                        var tmp       = "";
                        var tmpValue  = "";
                        var groupCout = 0;
                        foreach (var exp in expressions)
                        {
                            groupCout++;
                            tmp      = exp.Value.Trim('[', ']');
                            tmpValue = exp.Value;
                            if (!tmp.ToLower().EndsWith(".urlencode()"))
                            {
                                pattern = pattern.Replace(tmpValue, exp.Value.Replace(tmp, $"{tmp}.urlencode()"));
                            }

                            var objects = Parser.GetObjects(tmp);
                            if (objects != null && objects.Any())
                            {
                                foreach (var custObj in objects)
                                {
                                    if (custObj.Split('.').Length == 1)
                                    {
                                        IList <KClass> allClasses = new List <KClass>();
                                        if (documentValidator != null && documentValidator.entities != null && documentValidator.entities.Keys.Any(x => x == custObj.Trim('[', ']').ToLower()))
                                        {
                                            allClasses = documentValidator.entities[custObj.Trim('[', ']').ToLower()].Classes;
                                        }
                                        if (!allClasses.Any(x => x.ClassType == KClassType.BaseClass && x.Name.ToLower() == custObj.Trim('[', ']')))
                                        {
                                            if (!customVariables.ContainsKey(custObj.Trim('[', ']')?.ToLower()))
                                            {
                                                customVariables.Add(custObj.Trim('[', ']')?.ToLower(), groupCout);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    request.UrlPattern = string.Format("[[{0}]]/{1}", rootUrl, pattern);
                    if (pattern != null && pattern.ToLower().IndexOf(@"search/") != -1)
                    {
                        request.PageType = Models.Project.KitsunePageType.SEARCH;
                    }
                }
                //req.UrlPattern = pattern.Replace(kdl, req.UrlPattern);
                dynamicAttribute.Value = request.UrlPattern;
            }
            else if (filePath.ToLower().EndsWith(".dl"))
            {
                compileErrors.Add(CompileResultHelper.GetCompileError(ErrorCodeConstants.NoDLTagInDLPage));
            }
            else if (string.IsNullOrEmpty(request.UrlPattern))
            {
                request.UrlPattern = string.Format("[[{0}]]/{1}", rootUrl, filePath.ToLower());
            }
        }
Example #17
0
 public override void Process(ref HtmlNode node, HtmlAttribute dynamicAttribute, Dictionary <string, AliasReference> classNameAlias, Dictionary <int, string> classNameAliasdepth, int depth, string websiteId, ExpressionEvaluator evaluator, KEntity entity, dynamic websiteData, Models.Pagination viewDetails, string queryString, Dictionary <string, long> functionLog, bool isDetailsView = false, bool isNFSite = false, string developerId = null)
 {
 }
        public static List <PropertyPathSegment> ExtractPropertiesFromPath(string propertyPath, KEntity entity)
        {
            List <PropertyPathSegment> kProperties = new List <PropertyPathSegment>();

            var objectPathArray = propertyPath.ToLower().Split('.');
            var obClass         = new KClass();
            var obProperty      = new KProperty();
            var dataTypeClasses = new string[] { "str", "date", "number", "boolean", "kstring" };
            var currentProperty = string.Empty;
            var arrayRegex      = new System.Text.RegularExpressions.Regex(@".*\[(\d+)\]", System.Text.RegularExpressions.RegexOptions.Compiled);
            var functionRegex   = new System.Text.RegularExpressions.Regex(@"(\w+)\((.*)\)", System.Text.RegularExpressions.RegexOptions.Compiled);
            int?arrayIndex      = 0;
            int tempIndex       = 0;

            System.Text.RegularExpressions.Match arrayMatch    = null;
            System.Text.RegularExpressions.Match functionMatch = null;
            for (var i = 0; i < objectPathArray.Length; i++)
            {
                currentProperty = objectPathArray[i];
                arrayMatch      = arrayRegex.Match(currentProperty);
                arrayIndex      = null;
                if (arrayMatch != null && arrayMatch.Success)
                {
                    if (int.TryParse(arrayMatch.Groups[1].Value, out tempIndex))
                    {
                        arrayIndex = tempIndex;
                    }
                    currentProperty = currentProperty.Substring(0, currentProperty.IndexOf('['));
                }

                if (i == 0)
                {
                    obClass = entity.Classes.FirstOrDefault(x => x.ClassType == KClassType.BaseClass && x.Name.ToLower() == currentProperty);
                    if (obClass != null)
                    {
                        kProperties.Add(new PropertyPathSegment {
                            PropertyDataType = obClass.Name.ToLower(), PropertyName = currentProperty, Type = PropertyType.obj
                        });
                    }
                }
                else
                {
                    obProperty = obClass.PropertyList.FirstOrDefault(x => x.Name.ToLower() == currentProperty);
                    if (obProperty != null)
                    {
                        if ((obProperty.Type == PropertyType.array && !dataTypeClasses.Contains(obProperty.DataType?.Name?.ToLower())) || obProperty.Type == PropertyType.obj || obProperty.Type == PropertyType.kstring || obProperty.Type == PropertyType.phonenumber)
                        {
                            kProperties.Add(new PropertyPathSegment
                            {
                                PropertyName     = obProperty.Name.ToLower(),
                                PropertyDataType = obProperty.DataType.Name.ToLower(),
                                Index            = arrayIndex,
                                Type             = obProperty.Type
                            });

                            obClass = entity.Classes.FirstOrDefault(x => x.Name?.ToLower() == obProperty.DataType?.Name?.ToLower());
                        }
                        else
                        {
                            kProperties.Add(new PropertyPathSegment
                            {
                                PropertyName     = obProperty.Name.ToLower(),
                                PropertyDataType = obProperty.DataType.Name.ToLower(),
                                Index            = arrayIndex,
                                Type             = obProperty.Type
                            });
                        }
                    }
                    else
                    {
                        functionMatch = functionRegex.Match(currentProperty);
                        if (functionMatch.Success)
                        {
                            kProperties.Add(new PropertyPathSegment
                            {
                                PropertyName     = functionMatch.Groups[1].Value,
                                PropertyDataType = "function",
                                Type             = PropertyType.function
                            });
                        }
                    }
                }
            }
            return(kProperties);
        }
        public void ProcessNode(ref HtmlNode node, HtmlAttribute dynamicAttribute, Dictionary <string, AliasReference> classNameAlias, Dictionary <int, string> classNameAliasdepth, int depth, string websiteId, ExpressionEvaluator evaluator, KEntity entity, dynamic websiteData, Models.Pagination viewDetails, string queryString, Dictionary <string, long> functionLog, bool isDetailsView = false, bool isNFSite = false, string developerId = null)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            Process(ref node, dynamicAttribute, classNameAlias, classNameAliasdepth, depth, websiteId, evaluator, entity, websiteData, viewDetails, queryString, functionLog, isDetailsView, isNFSite);
            stopwatch.Stop();
            Helper.UpdateFunctionLog(functionLog, TagProcessorIdentifier, stopwatch.ElapsedMilliseconds);
        }
Example #20
0
        public override void Process(ref HtmlNode node, HtmlAttribute dynamicAttribute, Dictionary <string, AliasReference> classNameAlias, Dictionary <int, string> classNameAliasdepth, int depth, string websiteId, ExpressionEvaluator evaluator, KEntity entity, dynamic websiteData, Models.Pagination viewDetails, string queryString, Dictionary <string, long> functionLog, bool isDetailsView = false, bool isNFSite = false, string developerId = null)
        {
            Node result = LexerGenerator.Parse(Helper.TrimDelimiters(dynamicAttribute.Value));

            if (result.Token.Value == ACTIONS.Loop)
            {
                string referenceObject = result.Children[0].Children[0].Token.Value;
                string referenceName   = result.Children[2].Children[0].Token.Value?.ToLower();
                var    refObj          = evaluator.EvaluateExpression(referenceObject, entity, viewDetails, classNameAlias, websiteData, websiteData?._system?.kresult, queryString, out bool hasData, functionLog, isDetailsView, isNFSite);
                if (refObj.GetType() == typeof(string) && refObj == "")
                {
                    node = HtmlCommentNode.CreateNode("<!-- skip -->");
                    return;
                }
                string offsetObj = evaluator.EvaluateExpression(result.Children[6], entity, viewDetails, classNameAlias, websiteData, websiteData?._system?.kresult, queryString, out hasData, functionLog, isDetailsView, isNFSite, developerId).ToString();
                int.TryParse(offsetObj, out int offset);
                int iteration    = 0;
                int maxIteration = 0;
                if (dynamicAttribute.Value.IndexOf("offset") > 0)
                {
                    if (int.TryParse(viewDetails.currentpagenumber, out int currentPage) && currentPage > 0)
                    {
                        iteration = offset * (currentPage - 1);
                    }
                }
                else
                {
                    string iterationObj = evaluator.EvaluateExpression(result.Children[4], entity, viewDetails, classNameAlias, websiteData, websiteData?._system?.kresult, queryString, out hasData, functionLog, isDetailsView, isNFSite, developerId).ToString();
                    int.TryParse(iterationObj, out iteration);
                }
                maxIteration = iteration + offset;
                int objSize = (int)evaluator.GetObjectSize(refObj);
                maxIteration = (maxIteration < objSize) ? maxIteration : objSize;
                if (iteration > maxIteration)
                {
                    node = HtmlCommentNode.CreateNode("<!-- skip -->");
                    return;
                }
                else if (objSize == maxIteration && dynamicAttribute.Value.IndexOf("offset") > 0)
                {
                    viewDetails.nextpage.url = "#";
                    viewDetails.pagesize     = maxIteration - iteration + 1;
                }

                AliasReference aliasReference = new AliasReference
                {
                    referenceObject = null,
                    iteration       = iteration,
                    maxIteration    = maxIteration
                };
                if (!classNameAlias.ContainsKey(referenceName))
                {
                    classNameAlias.Add(referenceName, aliasReference);
                    classNameAliasdepth.Add(depth, referenceName);
                }
            }
            else if (result.Token.Value == ACTIONS.InLoop)
            {
                string referenceName   = result.Children[0].Children[0].Token.Value?.ToLower();
                string referenceObject = result.Children[2].Children[0].Token.Value;
                var    obj             = evaluator.EvaluateExpression(referenceObject, entity, viewDetails, classNameAlias, websiteData, websiteData?._system?.kresult, queryString, out bool hasData, functionLog, isDetailsView, isNFSite);
                if (obj.GetType() == typeof(string) && obj == "")
                {
                    node = HtmlCommentNode.CreateNode("<!-- skip -->");
                    return;
                }
                AliasReference aliasReference = new AliasReference();
                aliasReference.referenceObject = referenceObject;
                aliasReference.iteration       = 0;
                aliasReference.maxIteration    = (int)evaluator.GetObjectSize(obj);

                if (!classNameAlias.ContainsKey(referenceName))
                {
                    classNameAlias.Add(referenceName, aliasReference);
                    classNameAliasdepth.Add(depth, referenceName);
                }
            }
        }
        public KEntity GetKitsuneLanguage(string userEmail, string projectId, GetProjectDetailsResponseModel projectDetails, KEntity language, string userId)
        {
            if (language == null)
            {
                language = new KEntity()
                {
                    Classes = new List <KClass>(), EntityName = "_system"
                }
            }
            ;
            if (projectDetails != null && language != null)
            {
                var entityTemp = language;

                UpdateClassViews(userEmail, projectDetails, entityTemp);

                #region WebAction
                var webActions         = new WebActionAPI().GetWebActionList(userId).Result;
                var webActionBaseClass = new KClass
                {
                    ClassType   = KClassType.BaseClass,
                    Description = "Webaction",
                    Name        = "webactions",
                };
                IList <KProperty> PropertyList       = new List <KProperty>();
                IList <KClass>    webactionClassList = new List <KClass>();

                KClass webactionClass;
                if (webActions != null && webActions.WebActions != null)
                {
                    foreach (var webaction in webActions.WebActions)
                    {
                        //Webactions.webactionname
                        PropertyList.Add(new KProperty
                        {
                            DataType    = new DataType("wa" + webaction.Name.ToLower()),
                            Description = webaction.Name,
                            Name        = webaction.Name.ToLower(),
                            Type        = PropertyType.array
                        });

                        //Datatype (class) of the specific webaction
                        webactionClass = new KClass
                        {
                            ClassType    = KClassType.UserDefinedClass,
                            Description  = "Webaction products",
                            Name         = "wa" + webaction.Name.ToLower(),
                            PropertyList = webaction.Properties.Select(x => new KProperty
                            {
                                DataType    = new DataType(x.DataType),
                                Description = x.DisplayName,
                                Name        = x.PropertyName.ToLower(),
                                Type        = ConvertProperty(x.PropertyType),
                                IsRequired  = x.IsRequired
                            }).ToList()
                        };
                        webactionClass.PropertyList.Add(new KProperty
                        {
                            DataType    = new DataType("STR"),
                            Description = "Id",
                            Name        = "_id",
                            Type        = PropertyType.str
                        });
                        webactionClass.PropertyList.Add(new KProperty
                        {
                            DataType    = new DataType("DATE"),
                            Description = "Created on",
                            Name        = "createdon",
                            Type        = PropertyType.date
                        });
                        webactionClass.PropertyList.Add(new KProperty
                        {
                            DataType    = new DataType("DATE"),
                            Description = "Updated on",
                            Name        = "updatedon",
                            Type        = PropertyType.date
                        });
                        entityTemp.Classes.Add(webactionClass);
                    }
                }
                webActionBaseClass.PropertyList = PropertyList;
                entityTemp.Classes.Add(webActionBaseClass);
                #endregion

                if (projectId == projectDetails.ProjectId)
                {
                    language = entityTemp;
                }
            }
            return(language);
        }
 public override void Process(ref HtmlNode node, HtmlAttribute dynamicAttribute, Dictionary <string, AliasReference> classNameAlias, Dictionary <int, string> classNameAliasdepth, int depth, string websiteId, ExpressionEvaluator evaluator, KEntity entity, dynamic websiteData, Models.Pagination viewDetails, string queryString, Dictionary <string, long> functionLog, bool isDetailsView = false, bool isNFSite = false, string developerId = null)
 {
     if (Kitsune.Helper.Constants.WidgetRegulerExpression.IsMatch(dynamicAttribute.Value))
     {
         string attributeValue = evaluator.EvaluateExpression(dynamicAttribute.Value, entity, viewDetails, classNameAlias, websiteData, websiteData?._system?.kresult, queryString, out bool hasData, functionLog, isDetailsView, isNFSite, developerId).ToString();
         if (!hasData || (System.Boolean.TryParse(attributeValue, out bool attVal) && attVal))
         {
             node = HtmlCommentNode.CreateNode("<!-- skip -->");
         }
     }
 }
 static void UpdateClassViews(string userEmail, GetProjectDetailsResponseModel projectDetails, KEntity entity)
 {
     if (projectDetails != null)
     {
         foreach (var resource in projectDetails.Resources.Where(x => x.IsStatic == false && !string.IsNullOrEmpty(x.ClassName)))
         {
             entity.Classes.Add(new KClass
             {
                 ClassType    = KClassType.BaseClass,
                 Description  = resource.SourcePath.ToLower(),
                 Name         = resource.ClassName,
                 PropertyList = new List <KProperty>()
                 {
                     new KProperty
                     {
                         DataType    = new DataType("FUNCTION"),
                         Description = "Page link",
                         Name        = "GETURL",
                         Type        = PropertyType.function
                     },
                     new KProperty
                     {
                         DataType    = new DataType("FUNCTION"),
                         Description = "Set details page object",
                         Name        = "SETOBJECT",
                         Type        = PropertyType.function
                     },
                     new KProperty
                     {
                         DataType    = new DataType("LINK"),
                         Description = "First page link",
                         Name        = "FIRSTPAGE",
                         Type        = PropertyType.obj
                     },
                     new KProperty
                     {
                         DataType    = new DataType("LINK"),
                         Description = "Last page link",
                         Name        = "LASTPAGE",
                         Type        = PropertyType.obj
                     },
                     new KProperty
                     {
                         DataType    = new DataType("STR"),
                         Description = "Current page number",
                         Name        = "CURRENTPAGENUMBER",
                         Type        = PropertyType.str
                     },
                     new KProperty
                     {
                         DataType    = new DataType("LINK"),
                         Description = "Next page link",
                         Name        = "NEXTPAGE",
                         Type        = PropertyType.obj
                     },
                     new KProperty
                     {
                         DataType    = new DataType("STR"),
                         Description = "Offset of list page",
                         Name        = "OFFSET",
                         Type        = PropertyType.str
                     },
                     new KProperty
                     {
                         DataType    = new DataType("LINK"),
                         Description = "Previous page link",
                         Name        = "PREVIOUSPAGE",
                         Type        = PropertyType.obj
                     },
                     new KProperty
                     {
                         DataType    = new DataType("STR"),
                         Description = "Set object for the details page",
                         Name        = "SETOBJECT",
                         Type        = PropertyType.function
                     },
                 }
             });
         }
     }
 }
        public IEnumerable <CompilerError> ValidateExpression(string[] expr, int ind, string className, PropertyType type, int line, int position, string userEmail, KEntity entity)
        {
            if (expr.Length > ind)
            {
                var kDataClass = entity.Classes.Where(x => x.ClassType == KClassType.DataTypeClass);
                var len        = expr[ind].Length;
                expr[ind] = Kitsune.Helper.Constants.PropertyArrayExpression.Replace(expr[ind], "");
                var kClass = entity.Classes.FirstOrDefault(x => x.Name?.ToLower() == className);
                if (kClass == null)
                {
                    return new List <CompilerError> {
                               new CompilerError {
                                   LineNumber = line, LinePosition = position, Message = "'" + className + "' Class dose not exist in the schema"
                               }
                    }
                }
                ;

                var kProperty = kClass.PropertyList.FirstOrDefault(x => x.Name?.ToLower() == expr[ind]);
                if (kProperty != null)
                {
                    var dataType = (kProperty.Type != PropertyType.array ? kProperty.DataType.Name : kProperty.DataType.Name.Trim('[', ']'))?.ToLower();

                    if (kProperty.Type == PropertyType.function)
                    {
                        if (!Kitsune.Helper.Constants.FunctionRegularExpression.IsMatch(expr[ind]))
                        {
                            return new List <CompilerError> {
                                       new CompilerError {
                                           LineNumber = line, LinePosition = position, Message = expr[ind] + " is function but used like property"
                                       }
                            }
                        }
                        ;
                    }
                    else if (kProperty.Type == PropertyType.obj && "dynamic" == kProperty.DataType?.Name?.ToLower())
                    {
                        return(new List <CompilerError>());
                    }


                    var newClassName = ((kProperty.Type == PropertyType.array && len == expr[ind].Length) ? "array" : dataType.ToLower());
                    return(ValidateExpression(expr, ++ind, newClassName, kProperty.Type, line, position, userEmail, entity));
                }
                else
                {
                    return(new List <CompilerError> {
                        new CompilerError {
                            LineNumber = line, LinePosition = position, Message = "Property " + expr[ind] + " does not exist in the class " + className
                        }
                    });
                }
            }

            return(new List <CompilerError>());
        }
    }
}
        public override void Process(ref HtmlNode node, HtmlAttribute dynamicAttribute, Dictionary <string, AliasReference> classNameAlias, Dictionary <int, string> classNameAliasdepth, int depth, string websiteId, ExpressionEvaluator evaluator, KEntity entity, dynamic websiteData, Models.Pagination viewDetails, string queryString, Dictionary <string, long> functionLog, bool isDetailsView = false, bool isNFSite = false, string developerId = null)
        {
            List <string> amountList = new List <string>();
            string        amount     = Helper.TrimDelimiters(dynamicAttribute.Value);

            amount = evaluator.EvaluateExpression(amount, entity, viewDetails, classNameAlias, websiteData, websiteData?._system?.kresult, queryString, out bool hasData, functionLog, isDetailsView, isNFSite, developerId)?.ToString();
            dynamicAttribute.Value = amount;
            amountList.Add(amount);
            var checkSumAPIResponse = ApiHelper.GetKPayEncodedCheckSum(websiteId, amountList);

            amountList = checkSumAPIResponse.amounts;
            List <string> checkSumList = checkSumAPIResponse.checksums;

            node.SetAttributeValue("k-pay-checksum", checkSumList[0]);
        }
Example #26
0
        public List <CompileResult> BuildProject(string userEmail, string projectId, bool _isDev, int currentCompilerVersion)
        {
            try
            {
                var response                = new List <CompileResult>();
                var api                     = new CompilerAPI();
                var oldPage                 = false;
                var changedKDLOrPartial     = false;
                var filesCompiledCount      = 0;
                var buildStatusUpdateResult = true;
                var dict                    = new Dictionary <string, int>();
                System.Diagnostics.Stopwatch compileStopWatch = new System.Diagnostics.Stopwatch();
                Log.Information("Compilation started");
                dict.Add("LINK", 0);
                //List<BuildError> BuildErrors;
                var userId         = new UserAPI().GetUserId(userEmail);
                var project        = api.GetProjectDetailsApi(userEmail, projectId);
                var forceBuild     = false;
                var skipValidation = false;


                if (project == null)
                {
                    response.Add(new CompileResult {
                        Success = false, ErrorMessages = new List <CompilerError>()
                        {
                            new CompilerError {
                                Message = $"Project with projectid \"{projectId}\" not found."
                            }
                        }
                    });
                    return(response);
                }
                else
                {
                    forceBuild = project.CompilerVersion < currentCompilerVersion;
                }

                if (project.Resources.Any(x => Kitsune.Helper.Constants.ConfigFileRegularExpression.IsMatch(x.SourcePath)))
                {
                    var settings = api.GetProjectResourceDetailsApi(userEmail, projectId, HttpUtility.UrlEncode("/kitsune-settings.json"));
                    if (!string.IsNullOrEmpty(settings.HtmlSourceString))
                    {
                        try
                        {
                            var settingsOb = JsonConvert.DeserializeObject <dynamic>(settings.HtmlSourceString);
                            if (settingsOb.GetType() == typeof(JObject))
                            {
                                var cleanBuild = ((JObject)settingsOb).SelectToken("build.cleanBuild");
                                if (cleanBuild != null && !string.IsNullOrEmpty((string)cleanBuild))
                                {
                                    if ("true" == ((string)cleanBuild).ToLower())
                                    {
                                        forceBuild = true;
                                    }
                                }
                                var syntaxValidation = ((JObject)settingsOb).SelectToken("build.syntax_validation");
                                if (syntaxValidation != null && !string.IsNullOrEmpty((string)syntaxValidation))
                                {
                                    if ("true" == ((string)syntaxValidation).ToLower())
                                    {
                                        skipValidation = false;
                                    }
                                    else
                                    {
                                        skipValidation = true;
                                    }
                                    Console.WriteLine($"skipValidation:{skipValidation}");
                                }
                            }
                        }
                        catch { }
                    }
                }

                project.UserEmail = userEmail;
                project.Resources = project.Resources.Where(x => x.IsStatic == false && x.ResourceType != Kitsune.Models.Project.ResourceType.APPLICATION).ToList();
                var staticFileCount = project.Resources.Count();
                dict.Add("TOTAL", staticFileCount);

                var languageEntity = new KEntity
                {
                    Classes = new List <KClass>()
                };
                if (!string.IsNullOrEmpty(project.SchemaId))
                {
                    languageEntity = new LanguageAPI().GetLanguage(project.SchemaId, userId);
                }
                languageEntity = new KLanguageBase().GetKitsuneLanguage(userEmail, projectId, project, languageEntity, userId);

                #region Handle Project Modules
                var componentEntities = UpdateModuleReference(project);
                #endregion

                var partialPages = api.GetPartialPagesDetailsApi(userEmail, projectId, null);
                GetAuditProjectAndResourcesDetailsResponseModel auditProject = new GetAuditProjectAndResourcesDetailsResponseModel();
                DateTime latestBuildDate = DateTime.MinValue;
                if (project.Version > 1 && !forceBuild)
                {
                    var latestProjectVersion = project.Version - 1;
                    auditProject = api.GetAuditProjectAndResourcesDetails(userEmail, projectId, latestProjectVersion);
                }
                var latestBuild = api.GetLastCompletedBuild(userEmail, projectId);
                if (latestBuild != null && latestBuild.CreatedOn != null)
                {
                    latestBuildDate = latestBuild.CreatedOn;
                }

                var ToBeUpdatedResources = new List <CreateOrUpdateResourceRequestModel>();
                var CompiledResources    = new Dictionary <string, CompileResult>();
                var UncompiledResources  = new List <CompileResourceRequest>();

                //put partial pages first
                var partialResources = project.Resources.FindAll(x => x.PageType == Kitsune.Models.Project.KitsunePageType.PARTIAL);
                if (partialResources.Any())
                {
                    foreach (var resource in partialResources)
                    {
                        project.Resources.Remove(resource);
                        project.Resources.Insert(0, resource);
                    }
                }
                foreach (var page in project.Resources)
                {
                    oldPage = false;
                    var resource = api.GetProjectResourceDetailsApi(userEmail, projectId, HttpUtility.UrlEncode(page.SourcePath));
                    // page.IsStatic = KitsuneCompiler.IsResourceStatic(resource.HtmlSourceString, page.SourcePath);
                    if (!page.IsStatic)
                    {
                        var compiled = false;
                        var document = new HtmlDocument();
                        Console.WriteLine("Page: " + page.SourcePath);
                        var req   = new CompileResourceRequest();
                        var outsd = new CompileResult();
                        if (project.Version > 1 && !forceBuild)
                        {
                            oldPage = auditProject.Resources.Any(x => x.SourcePath == page.SourcePath);
                        }
                        GetFileFromS3RequestModel resourceTreeRequest = new GetFileFromS3RequestModel
                        {
                            SourcePath = string.Format(CompilerConstants.TreeFileName, page.SourcePath),
                            ProjectId  = page.ProjectId,
                            BucketName = project.BucketNames.demo
                        };
                        var resourceTreePresent = api.GetFileFromS3(resourceTreeRequest);
                        if (!changedKDLOrPartial && project.Version > 1 && oldPage && page.UpdatedOn <= latestBuildDate && !string.IsNullOrEmpty(resourceTreePresent))
                        {
                            var samePage = auditProject.Resources.Find(x => x.SourcePath == page.SourcePath);
                            GetFileFromS3RequestModel FileRequest = new GetFileFromS3RequestModel
                            {
                                SourcePath = samePage.SourcePath,
                                ProjectId  = samePage.ProjectId,
                                BucketName = project.BucketNames.demo,
                                Compiled   = true,
                                Version    = samePage.Version
                            };
                            outsd = new CompileResult()
                            {
                                CompiledString = api.GetFileFromS3(FileRequest),
                                Success        = true
                            };
                            req.PageType   = samePage.PageType;
                            req.UrlPattern = samePage.UrlPattern;
                            req.SourcePath = samePage.SourcePath;
                            compiled       = false;
                        }
                        else
                        {
                            req = new CompileResourceRequest {
                                SourcePath = page.SourcePath, FileContent = resource.HtmlSourceString, UserEmail = project.UserEmail, ProjectId = projectId, IsDev = _isDev, IsPublish = true, IsStatic = page.IsStatic, IsDefault = page.IsDefault, ClassName = page.ClassName, UrlPattern = page.UrlPattern, KObject = page.KObject, PageType = page.PageType, ResourceType = page.ResourceType
                            };
                            //Compile config file

                            compileStopWatch.Reset();
                            compileStopWatch.Start();
                            if (skipValidation)
                            {
                                outsd = new CompileResult();
                                outsd.CompiledString = req.FileContent;
                                outsd.PageName       = req.SourcePath;
                                req.UrlPattern       = req.SourcePath;
                                page.UrlPattern      = req.SourcePath;
                                outsd.Success        = true;
                            }
                            else if (Kitsune.Helper.Constants.ConfigFileRegularExpression.IsMatch(req.SourcePath))
                            {
                                outsd = KitsuneCompiler.ValidateJsonConfig(new ValidateConfigRequestModel
                                {
                                    File = new ConfigFile {
                                        Content = req.FileContent
                                    },
                                    UserEmail = req.UserEmail
                                });
                                outsd.CompiledString = req.FileContent;
                                outsd.PageName       = req.SourcePath;
                                req.UrlPattern       = req.SourcePath;
                                page.UrlPattern      = req.SourcePath;
                            }
                            //Compile dynamic html file
                            else
                            {
                                Console.WriteLine($"Compiling : {req.SourcePath}");
                                outsd = KitsuneCompiler.CompileHTML(req, out document, project, languageEntity, partialPages, componentEntities: componentEntities);
                            }

                            if (!outsd.Success)
                            {
                                response.Add(outsd);
                            }
                            else
                            {
                                CompileLog(req.SourcePath, compileStopWatch.ElapsedMilliseconds.ToString());

                                // Console.WriteLine($"'{req.SourcePath}'-{compileStopWatch.ElapsedMilliseconds.ToString()}");
                                ResourceMetaInfo metaInfo = new ResourceMetaInfo();
                                try
                                {
                                    var tagsToIgnore = new List <string>();
                                    if (outsd.CustomVariables != null)
                                    {
                                        tagsToIgnore.AddRange(outsd.CustomVariables.Keys);
                                    }
                                    metaInfo           = ResourceMetaInfoGenerator.MetaInfo(req, outsd.CompiledString, project, languageEntity, tagsToIgnore);
                                    outsd.MetaClass    = metaInfo?.metaClass;
                                    outsd.MetaProperty = metaInfo?.Property;
                                }
                                catch (Exception ex)
                                {
                                    metaInfo = new ResourceMetaInfo
                                    {
                                        IsError = true,
                                        Message = string.Format("Excepiton occured while generating metainfo: {0}", ex.Message)
                                    };
                                }
                                CompiledResources.Add(string.Format("{0}:{1}", req.ProjectId, req.SourcePath), outsd);
                            }

                            if (!changedKDLOrPartial && oldPage)
                            {
                                var samePage = auditProject.Resources.Find(x => x.SourcePath == page.SourcePath);
                                if (samePage.UrlPattern != req.UrlPattern)
                                {
                                    changedKDLOrPartial = true;
                                }
                                if (samePage.PageType == Kitsune.Models.Project.KitsunePageType.PARTIAL)
                                {
                                    changedKDLOrPartial = true;
                                }
                            }
                            compiled = true;
                        }

                        //Replacing the aws path to the version controlled folder
                        //outsd.CompiledString = KitsuneCompiler.AddAuditAssetsPath(projectId, outsd.CompiledString, project.Version);


                        //Save compiled resource to kitsune resource collection
                        var updatePageRequest = new CreateOrUpdateResourceRequestModel
                        {
                            Errors          = null,
                            FileContent     = req.FileContent,
                            SourcePath      = req.SourcePath,
                            ClassName       = req.ClassName,
                            ProjectId       = req.ProjectId,
                            UserEmail       = req.UserEmail,
                            UrlPattern      = req.UrlPattern,
                            IsStatic        = req.IsStatic,
                            IsDefault       = req.IsDefault,
                            PageType        = req.PageType,
                            KObject         = req.KObject,
                            CustomVariables = outsd.CustomVariables,
                            Offset          = req.Offset
                        };



                        if (compiled)
                        {
                            ToBeUpdatedResources.Add(updatePageRequest);
                            filesCompiledCount += 1;

                            if (filesCompiledCount % 5 == 0)
                            {
                                try
                                {
                                    dict["LINK"]            = filesCompiledCount;
                                    buildStatusUpdateResult = api.UpdateBuildStatus(userEmail, new CreateOrUpdateKitsuneStatusRequestModel
                                    {
                                        ProjectId = projectId,
                                        Compiler  = dict,
                                        Stage     = BuildStatus.Compiled
                                                    //Error = BuildErrors
                                    });
                                }
                                catch (Exception ex)
                                {
                                }
                            }
                        }
                        else if (!compiled)
                        {
                            UncompiledResources.Add(new CompileResourceRequest
                            {
                                FileContent = resource.HtmlSourceString,
                                SourcePath  = page.SourcePath,
                                IsStatic    = page.IsStatic,
                                IsDefault   = page.IsDefault,
                                UrlPattern  = page.UrlPattern,
                                ClassName   = page.ClassName,
                            });
                        }
                    }
                }
                //Exception operations on uncompiled Pages
                if (!skipValidation && UncompiledResources.Any())
                {
                    if (changedKDLOrPartial)
                    {
                        foreach (var currpage in UncompiledResources)
                        {
                            var document = new HtmlDocument();
                            var req      = new CompileResourceRequest {
                                SourcePath = currpage.SourcePath, FileContent = currpage.FileContent, UserEmail = project.UserEmail, ProjectId = projectId, IsDev = _isDev, IsPublish = true, IsStatic = currpage.IsStatic, IsDefault = currpage.IsDefault, ClassName = currpage.ClassName, UrlPattern = currpage.UrlPattern
                            };

                            compileStopWatch.Reset();
                            compileStopWatch.Start();

                            Console.WriteLine($"Compiling UncompiledResources : {currpage.SourcePath}");

                            var outsd = KitsuneCompiler.CompileHTML(req, out document, project, languageEntity, partialPages, componentEntities: componentEntities);

                            if (!outsd.Success)
                            {
                                response.Add(outsd);
                            }
                            else
                            {
                                CompileLog(currpage.SourcePath, compileStopWatch.ElapsedMilliseconds.ToString());

                                ResourceMetaInfo metaInfo = new ResourceMetaInfo();
                                try
                                {
                                    var tagsToIgnore = new List <string>();
                                    if (outsd.CustomVariables != null)
                                    {
                                        tagsToIgnore.AddRange(outsd.CustomVariables.Keys);
                                    }
                                    metaInfo           = ResourceMetaInfoGenerator.MetaInfo(req, outsd.CompiledString, project, languageEntity, tagsToIgnore);
                                    outsd.MetaClass    = metaInfo?.metaClass;
                                    outsd.MetaProperty = metaInfo?.Property;
                                }
                                catch (Exception ex)
                                {
                                    metaInfo = new ResourceMetaInfo
                                    {
                                        IsError = true,
                                        Message = string.Format("Excepiton occured while generating metainfo: {0}", ex.Message)
                                    };
                                }
                                CompiledResources.Add(string.Format("{0}:{1}", req.ProjectId, req.SourcePath), outsd);
                            }
                            //outsd.CompiledString = KitsuneCompiler.AddAuditAssetsPath(projectId, outsd.CompiledString, project.Version);
                            ToBeUpdatedResources.Add(new CreateOrUpdateResourceRequestModel
                            {
                                Errors          = null,
                                FileContent     = req.FileContent,
                                SourcePath      = req.SourcePath,
                                ClassName       = req.ClassName,
                                ProjectId       = req.ProjectId,
                                UserEmail       = req.UserEmail,
                                UrlPattern      = req.UrlPattern,
                                IsStatic        = req.IsStatic,
                                IsDefault       = req.IsDefault,
                                PageType        = req.PageType,
                                KObject         = req.KObject,
                                Offset          = req.Offset,
                                CustomVariables = outsd.CustomVariables
                            });
                            filesCompiledCount += 1;
                            if (filesCompiledCount % 5 == 0)
                            {
                                try
                                {
                                    dict["LINK"]            = filesCompiledCount;
                                    buildStatusUpdateResult = api.UpdateBuildStatus(userEmail, new CreateOrUpdateKitsuneStatusRequestModel
                                    {
                                        ProjectId = projectId,
                                        Compiler  = dict,
                                        Stage     = BuildStatus.Compiled
                                                    //Error = BuildErrors
                                    });
                                }
                                catch (Exception ex)
                                {
                                }
                            }
                        }
                    }
                    else
                    {
                        foreach (var currpage in UncompiledResources)
                        {
                            //SubmittedResources.Add(new CreateOrUpdateResourceRequest
                            //{
                            //    Errors = null,
                            //    FileContent = currpage.HtmlSourceString,
                            //    SourcePath = currpage.SourcePath.Trim().ToUpper(),
                            //    ClassName = currpage.ClassName,
                            //    ProjectId = currpage.ProjectId,
                            //    UserEmail = currpage.UserEmail,
                            //    UrlPattern = currpage.UrlPattern,
                            //    IsStatic = currpage.IsStatic,
                            //    IsDefault = currpage.IsDefault,
                            //    PageType = currpage.PageType,
                            //    KObject = currpage.KObject
                            //});
                            filesCompiledCount += 1;
                            if (filesCompiledCount % 5 == 0)
                            {
                                try
                                {
                                    dict["LINK"]            = filesCompiledCount;
                                    buildStatusUpdateResult = api.UpdateBuildStatus(userEmail, new CreateOrUpdateKitsuneStatusRequestModel
                                    {
                                        ProjectId = projectId,
                                        Compiler  = dict,
                                        Stage     = BuildStatus.Compiled
                                                    //Error = BuildErrors
                                    });
                                }
                                catch (Exception ex)
                                {
                                }
                            }
                        }
                    }
                }

                try
                {
                    dict["LINK"]            = filesCompiledCount;
                    buildStatusUpdateResult = api.UpdateBuildStatus(userEmail, new CreateOrUpdateKitsuneStatusRequestModel
                    {
                        ProjectId = projectId,
                        Compiler  = dict,
                        Stage     = BuildStatus.Compiled
                                    //Error = BuildErrors
                    });
                }
                catch (Exception ex)
                {
                }
                if (!response.Any())
                {
                    List <UrlPatternRegexDetails> UrlPatternRegexList = new List <UrlPatternRegexDetails>();
                    foreach (var resource in project.Resources.Where(x => !string.IsNullOrEmpty(x.UrlPattern)))
                    {
                        var UrlPatternRegex = KitsuneCommonUtils.GenerateUrlPatternRegex(resource.UrlPattern.Substring(resource.UrlPattern.IndexOf("/") + 1), resource.SourcePath);
                        UrlPatternRegexList.Add(new UrlPatternRegexDetails
                        {
                            SourcePath      = resource.SourcePath,
                            UrlPattern      = resource.UrlPattern,
                            UrlPatternRegex = UrlPatternRegex
                        });
                    }
                    var UrlPatternRegexDistinct = UrlPatternRegexList.GroupBy(x => x.UrlPatternRegex).Select(x => new { Regex = x.Key, Count = x.Count() }).Where(x => x.Count > 1).ToList();
                    if (UrlPatternRegexDistinct != null && UrlPatternRegexDistinct.Any())
                    {
                        int regexMatchesCount = 1;
                        var message           = "Url pattern conflict : \n";
                        var pageName          = string.Empty;
                        foreach (var pattern in UrlPatternRegexDistinct)
                        {
                            var result = UrlPatternRegexList.FindAll(x => x.UrlPatternRegex == pattern.Regex);
                            pageName = result?.First()?.SourcePath;
                            var partMessage = string.Join(", ", result.Select(x => x.SourcePath).ToArray());
                            message           += regexMatchesCount.ToString() + ": " + partMessage + "\n";
                            regexMatchesCount += 1;
                        }
                        return(new List <CompileResult> {
                            new CompileResult {
                                ErrorMessages = new List <CompilerError> {
                                    new CompilerError {
                                        Message = message,
                                        LineNumber = 1,
                                        LinePosition = 1
                                    }
                                },
                                Success = false
                            }
                        });
                    }
                    List <ResourcePropertyPosition> AllResourcesMeta = new List <ResourcePropertyPosition>();
                    var metaClassCompletion = true;
                    foreach (var resource in ToBeUpdatedResources)
                    {
                        Console.WriteLine($"Uploading : {resource?.SourcePath}");
                        resource.UrlPatternRegex = UrlPatternRegexList.Find(x => x.SourcePath == resource.SourcePath).UrlPatternRegex;
                        var retryCount = 0;
                        do
                        {
                            var isUploaded = api.CreateOrUpdateResourceApi(resource);
                            if (!isUploaded)
                            {
                                Console.WriteLine($"Upload Failed.. retrying {retryCount}..");
                                retryCount++;
                                if (retryCount >= 3)
                                {
                                    return new List <CompileResult> {
                                               new CompileResult {
                                                   ErrorMessages = new List <CompilerError> {
                                                       new CompilerError {
                                                           Message = string.Format("Faild to save to DB for file : '{0}'", resource.SourcePath), LineNumber = 1, LinePosition = 1
                                                       }
                                                   }, Success = false
                                               }
                                    }
                                }
                                ;
                            }
                            else
                            {
                                retryCount = 0;
                            }
                        } while (retryCount != 0);

                        if (CompiledResources.ContainsKey(string.Format("{0}:{1}", resource.ProjectId, resource.SourcePath)))
                        {
                            var currentCompiledResource = CompiledResources[string.Format("{0}:{1}", resource.ProjectId, resource.SourcePath)];
                            SaveFileContentToS3RequestModel resourceContent = new SaveFileContentToS3RequestModel
                            {
                                ProjectId   = resource.ProjectId,
                                BucketName  = project.BucketNames.demo,
                                SourcePath  = resource.SourcePath,
                                FileContent = currentCompiledResource.CompiledString
                            };
                            var compiledStringResult = api.SaveFileContentToS3(resourceContent);
                            if (compiledStringResult == null)
                            {
                                return new List <CompileResult> {
                                           new CompileResult {
                                               ErrorMessages = new List <CompilerError> {
                                                   new CompilerError {
                                                       Message = string.Format("Faild to save to Demo Bucket for file : '{0}'", resource.SourcePath), LineNumber = 1, LinePosition = 1
                                                   }
                                               }, Success = false
                                           }
                                }
                            }
                            ;
                            //Save compiled (.kc) file
                            if (currentCompiledResource.KitsunePage != null)
                            {
                                var jsonSerializeSettings = new JsonSerializerSettings();

                                jsonSerializeSettings.TypeNameHandling = TypeNameHandling.Auto;
                                string output = JsonConvert.SerializeObject(currentCompiledResource.KitsunePage, Formatting.None, jsonSerializeSettings);

                                resourceContent = new SaveFileContentToS3RequestModel
                                {
                                    ProjectId   = resource.ProjectId,
                                    BucketName  = project.BucketNames.demo,
                                    SourcePath  = $"{resource.SourcePath}.kc",
                                    FileContent = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(output)),
                                    base64      = true
                                };
                                compiledStringResult = api.SaveFileContentToS3(resourceContent);
                                if (compiledStringResult == null)
                                {
                                    return new List <CompileResult> {
                                               new CompileResult {
                                                   ErrorMessages = new List <CompilerError> {
                                                       new CompilerError {
                                                           Message = string.Format("Faild to save to Demo Bucket for file : '{0}'", resource.SourcePath), LineNumber = 1, LinePosition = 1
                                                       }
                                                   }, Success = false
                                               }
                                    }
                                }
                                ;
                            }

                            try
                            {
                                if (Kitsune.Helper.Constants.DynamicFileExtensionRegularExpression.IsMatch(resource.SourcePath.ToLower()))
                                {
                                    if (currentCompiledResource.MetaClass == null)
                                    {
                                        metaClassCompletion = false;
                                        throw new Exception(string.Format("Meta Class is null for resource: {0}", resource.SourcePath));
                                    }
                                    var serializedMetaClass = MetaHelper.ProtoSerializer(CompiledResources[string.Format("{0}:{1}", resource.ProjectId, resource.SourcePath)].MetaClass);

                                    if (string.IsNullOrEmpty(serializedMetaClass))
                                    {
                                        throw new Exception(string.Format("Meta Class serialization failed for resource: {0}", resource.SourcePath));
                                    }
                                    //return new List<CompileResult> { new CompileResult { ErrorMessages = new List<CompilerError> { new CompilerError { Message = string.Format("Faild to serialize meta Class for : {0}", resource.SourcePath), LineNumber = 1, LinePosition = 1 } }, Success = false } };
                                    resourceContent = new SaveFileContentToS3RequestModel
                                    {
                                        ProjectId   = resource.ProjectId,
                                        BucketName  = project.BucketNames.demo,
                                        SourcePath  = string.Format(CompilerConstants.TreeFileName, resource.SourcePath),
                                        FileContent = serializedMetaClass,
                                        base64      = true
                                    };
                                    var metaClassResult = api.SaveFileContentToS3(resourceContent);
                                    if (metaClassResult == null)
                                    {
                                        throw new Exception(string.Format("Meta Class .k file not saved for resource: {0}", resource.SourcePath));
                                    }
                                    //return new List<CompileResult> { new CompileResult { ErrorMessages = new List<CompilerError> { new CompilerError { Message = string.Format("Faild to save meta class to Demo Bucket for : '{0}'", resource.SourcePath), LineNumber = 1, LinePosition = 1 } }, Success = false } };
                                    metaClassResult = null;

                                    AllResourcesMeta.Add(new ResourcePropertyPosition
                                    {
                                        SourcePath = resource.SourcePath,
                                        UrlPattern = resource.UrlPattern,
                                        Properties = CompiledResources[string.Format("{0}:{1}", resource.ProjectId, resource.SourcePath)].MetaClass
                                    });
                                }
                            }
                            catch (Exception ex)
                            {
                                //ToDo: Log MetaInfo Error
                            }
                        }
                    }
                    try
                    {
                        if (AllResourcesMeta.Any() && metaClassCompletion)
                        {
                            MetaGraphNode             metaGraphResult = new MetaGraphNode();
                            GetFileFromS3RequestModel GraphRequest    = new GetFileFromS3RequestModel
                            {
                                SourcePath = string.Format(CompilerConstants.GraphFileName, projectId),
                                ProjectId  = projectId,
                                BucketName = project.BucketNames.demo
                            };
                            var serializedMetaGraph = api.GetFileFromS3(GraphRequest);
                            var metaGraphBuilder    = new MetaGraphBuilder();
                            if (serializedMetaGraph != null)
                            {
                                var metaGraph = MetaHelper.ProtoDeserialize <MetaGraphNode>(serializedMetaGraph);
                                if (metaGraph == null)
                                {
                                    throw new Exception("Meta Graph Deserialization failed");
                                }
                                //return new List<CompileResult> { new CompileResult { ErrorMessages = new List<CompilerError> { new CompilerError { Message = "Failed to deserialize Reference Graph", LineNumber = 1, LinePosition = 1 } }, Success = false } };
                                metaGraphResult = metaGraphBuilder.CreateGraph(AllResourcesMeta, metaGraph);
                            }
                            else
                            {
                                metaGraphResult = metaGraphBuilder.CreateGraph(AllResourcesMeta);
                            }
                            if (metaGraphResult == null)
                            {
                                throw new Exception("Meta Graph creation failed");
                            }
                            //return new List<CompileResult> { new CompileResult { ErrorMessages = new List<CompilerError> { new CompilerError { Message = "Faild to create reference Graph", LineNumber = 1, LinePosition = 1 } }, Success = false } };
                            var newSerializedMetaGraph = MetaHelper.ProtoSerializer(metaGraphResult);
                            if (string.IsNullOrEmpty(newSerializedMetaGraph))
                            {
                                throw new Exception("Meta Graph serialization failed");
                            }
                            //return new List<CompileResult> { new CompileResult { ErrorMessages = new List<CompilerError> { new CompilerError { Message = string.Format("Faild to serialize meta Class for : {0}", projectId), LineNumber = 1, LinePosition = 1 } }, Success = false } };
                            SaveFileContentToS3RequestModel graphContent = new SaveFileContentToS3RequestModel
                            {
                                ProjectId   = projectId,
                                BucketName  = project.BucketNames.demo,
                                SourcePath  = string.Format(CompilerConstants.GraphFileName, projectId),
                                FileContent = newSerializedMetaGraph,
                                base64      = true
                            };
                            var graphSaveResult = api.SaveFileContentToS3(graphContent);
                            if (graphSaveResult == null)
                            {
                                throw new Exception("Meta Graph file not saved");
                            }
                            //return new List<CompileResult> { new CompileResult { ErrorMessages = new List<CompilerError> { new CompilerError { Message = "Faild to save Graph to Demo Bucket", LineNumber = 1, LinePosition = 1 } }, Success = false } };
                        }
                    }
                    catch (Exception ex)
                    {
                        //ToDo: Log MetaInfo Error
                    }

                    //Update the project version

                    if (project.CompilerVersion != currentCompilerVersion)
                    {
                        APIHelpers.UpdateProjectCompilerVersion(userEmail, projectId, currentCompilerVersion);
                    }
                }
                return(response);
            }
            catch (Exception ex)
            {
                Log.Error($"BuildProject : Exception : {ex.Message}, {ex.StackTrace}, {(ex.Data != null ? ex.Data.Count > 0 ? Newtonsoft.Json.JsonConvert.SerializeObject(ex.Data) : "" : "")}");
                return(new List <CompileResult> {
                    new CompileResult {
                        ErrorMessages = new List <CompilerError> {
                            new CompilerError {
                                Message = "BuildProject : Exception :  Something went wrong. Please try again.", LineNumber = 1, LinePosition = 1
                            }
                        }, Success = false
                    }
                });
            }
        }
        /// <summary>
        /// validate expression.
        /// </summary>
        /// <param name="expr"></param>
        /// <param name="ind"></param>
        /// <param name="className"></param>
        /// <param name="type"></param>
        /// <param name="line"></param>
        /// <param name="position"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        private IEnumerable <CompilerError> ValidateExpression(string[] expr, int ind, string className, PropertyType type, int line, int position, KEntity entity)
        {
            if (expr.Length > ind)
            {
                var len = expr[ind].Length;
                expr[ind] = Constants.PropertyArrayExpression.Replace(expr[ind], "");
                var kClass = entity.Classes.FirstOrDefault(x => x.Name?.ToLower() == className);
                if (kClass == null)
                {
                    return new List <CompilerError> {
                               new CompilerError {
                                   LineNumber = line, LinePosition = position, Message = String.Format(ErrorCodeConstants.ClassDoesNotExistInSchema, className)
                               }
                    }
                }
                ;

                var kProperty = kClass.PropertyList.FirstOrDefault(x => x.Name?.ToLower() == expr[ind]);
                if (kProperty != null)
                {
                    var dataType = (kProperty.Type != PropertyType.array ? kProperty.DataType.Name : kProperty.DataType.Name.Trim('[', ']'))?.ToLower();

                    if (kProperty.Type == PropertyType.function)
                    {
                        if (!Constants.FunctionRegularExpression.IsMatch(expr[ind]))
                        {
                            return new List <CompilerError> {
                                       new CompilerError {
                                           LineNumber = line, LinePosition = position, Message = String.Format(ErrorCodeConstants.FunctionUsedLikeProperty, expr[ind])
                                       }
                            }
                        }
                        ;
                    }
                    else if (kProperty.Type == PropertyType.obj && "dynamic" == kProperty.DataType?.Name?.ToLower())
                    {
                        return(new List <CompilerError>());
                    }

                    var newClassName = ((kProperty.Type == PropertyType.array && len == expr[ind].Length) ? "array" : dataType.ToLower());
                    return(ValidateExpression(expr, ++ind, newClassName, kProperty.Type, line, position, entity));
                }
                else
                {
                    return(new List <CompilerError> {
                        new CompilerError {
                            LineNumber = line, LinePosition = position, Message = String.Format(ErrorCodeConstants.PropertyDoesNotExist, expr[ind], className)
                        }
                    });
                }
            }
            return(new List <CompilerError>());
        }
        /// <summary>
        /// Validate k-tags and expressions in the document.
        /// </summary>
        /// <param name="document">Incoming document</param>
        /// <param name="request">Incoming request</param>
        /// <param name="compileErrors">list of errors during compile</param>
        /// <param name="kentity">project language</param>
        /// <param name="customVariables">custom variables found during compilation</param>
        /// <param name="rootUrl">root url</param>
        /// <param name="filePath">file path</param>
        public void ValidateDocument(HtmlDocument document, CompileResourceRequest request, List <CompilerError> compileErrors, KEntity kentity, Dictionary <string, int> customVariables, string rootUrl, string filePath, GetProjectDetailsResponseModel projectDetails, List <KEntity> componentsEntity = null)
        {
            Dictionary <string, bool>   objectNamesValidated  = new Dictionary <string, bool>();
            Dictionary <string, string> classNameAlias        = new Dictionary <string, string>();
            Dictionary <int, string>    classNameAliasLevel   = new Dictionary <int, string>();
            List <MatchNode>            objectNamesToValidate = new List <MatchNode>();

            entities.Add(kentity.EntityName, kentity);
            defaultEntity = kentity.EntityName;
            if (componentsEntity != null && componentsEntity.Any())
            {
                foreach (var comEntity in componentsEntity)
                {
                    if (!entities.Keys.Contains(comEntity.EntityName))
                    {
                        entities.Add(comEntity.EntityName, comEntity);
                    }
                }
            }

            var baseClassList = entities.SelectMany(x => x.Value?.Classes?.Where(y => y.ClassType == KClassType.BaseClass)?.ToList());

            HtmlNode      node = document.DocumentNode;
            List <string> dynamicTagDescriptors = GetDynamicTagDescriptors(typeof(LanguageAttributes));
            int           level = 0;

            while (node != null)
            {
                if (node.NodeType == HtmlNodeType.Element)
                {
                    var dynamicAttributes = node.Attributes.Where(x => dynamicTagDescriptors.Contains(x.Name.ToLower()));
                    for (int i = 0; i < dynamicAttributes.Count(); i++)
                    {
                        if (!string.IsNullOrEmpty(dynamicAttributes.ElementAt(i).Value))
                        {
                            Processor processor = ProcessorFactory.GetProcessor(dynamicAttributes.ElementAt(i).Name);
                            processor.ProcessNode(request, compileErrors, customVariables, rootUrl, filePath, classNameAlias, classNameAliasLevel, level, node, dynamicAttributes.ElementAt(i), objectNamesToValidate, this);
                        }
                        //k-partial k-norepeat attribute can be empty
                        else if (dynamicAttributes.ElementAt(i).Name?.ToLower() != LanguageAttributes.KPartial.GetDescription()?.ToLower() &&
                                 dynamicAttributes.ElementAt(i).Name?.ToLower() != LanguageAttributes.KNoRepeat.GetDescription()?.ToLower())
                        {
                            compileErrors.Add(CompileResultHelper.GetCompileError(string.Format(ErrorCodeConstants.InvalidKitsuneTagValue,
                                                                                                dynamicAttributes.ElementAt(i).Name,
                                                                                                dynamicAttributes.ElementAt(i).Line, dynamicAttributes.ElementAt(i).LinePosition)));
                        }
                    }
                    if (node.Name.Equals(LanguageAttributes.KScript.GetDescription(), StringComparison.InvariantCultureIgnoreCase))
                    {
                        Processor processor = ProcessorFactory.GetProcessor(node.Name.ToLower());
                        processor.ProcessNode(request, compileErrors, customVariables, rootUrl, filePath, classNameAlias, classNameAliasLevel, level, node, null, objectNamesToValidate, this);
                    }
                }

                if (node.HasChildNodes)
                {
                    node = node.FirstChild;
                    level++;
                }
                else
                {
                    ValidateExpressions(compileErrors, entities, objectNamesValidated, classNameAlias, baseClassList, node, objectNamesToValidate, customVariables, projectDetails);
                    if (node.NextSibling != null)
                    {
                        node = node.NextSibling;
                        ClearNameAliases(classNameAlias, classNameAliasLevel, level);
                    }
                    else
                    {
                        while (node.ParentNode != null && node.ParentNode.NextSibling == null)
                        {
                            node = node.ParentNode;
                            ValidateExpressions(compileErrors, entities, objectNamesValidated, classNameAlias, baseClassList, node, objectNamesToValidate, customVariables, projectDetails);
                            level--;
                            ClearNameAliases(classNameAlias, classNameAliasLevel, level);
                        }
                        node = node?.ParentNode;
                        if (node != null)
                        {
                            ValidateExpressions(compileErrors, entities, objectNamesValidated, classNameAlias, baseClassList, node, objectNamesToValidate, customVariables, projectDetails);
                        }
                        node = node?.NextSibling;
                        level--;
                        ClearNameAliases(classNameAlias, classNameAliasLevel, level);
                    }
                }
            }
        }
        public List <CompilerError> Validate(KEntity baseLanguageEntity, string[] resourceLines, string userEmail, string themeId, List <KEntity> componentsEntity = null)
        {
            var result = new List <CompilerError>();
            Dictionary <string, KEntity> entities = new Dictionary <string, KEntity>();

            entities.Add(baseLanguageEntity.EntityName, baseLanguageEntity);
            if (componentsEntity != null && componentsEntity.Any())
            {
                foreach (var comEntity in componentsEntity)
                {
                    if (!entities.Keys.Contains(comEntity.EntityName))
                    {
                        entities.Add(comEntity.EntityName, comEntity);
                    }
                }
            }
            var kitsuneObjects = new List <Kitsune.Helper.MatchNode>();
            var repeatIterator = string.Empty;

            try
            {
                #region Validating Resource Html
                var index = 0;
                foreach (var resourceLine in resourceLines)
                {
                    List <Helper.MatchNode> attributeValue = null;

                    attributeValue = Kitsune.Helper.HtmlHelper.GetExpressionFromElement(resourceLine, index + 1);
                    kitsuneObjects = new List <Kitsune.Helper.MatchNode>();
                    if (attributeValue != null && attributeValue.Any())
                    {
                        repeatIterator = string.Empty;
                        List <string> objects = null;
                        foreach (var attr in attributeValue)
                        {
                            kitsuneObjects = new List <Kitsune.Helper.MatchNode>();
                            if (Kitsune.Helper.Constants.KRepeatPatternRegex.IsMatch(attr.Value.Trim()))
                            {
                                repeatIterator = Kitsune.Helper.Constants.KRepeatPatternRegex.Match(attr.Value.Trim()).Groups[3].Value.Trim();
                            }
                            try
                            {
                                objects = Parser.GetObjects(attr.Value);
                            }
                            catch (Exception ex)
                            {
                                result.Add(new CompilerError {
                                    Message = ex.Message, LineNumber = index, LinePosition = resourceLine.IndexOf(attr.Value)
                                });
                                return(result);
                            }
                            foreach (var obj in objects)
                            {
                                kitsuneObjects.Add(new Kitsune.Helper.MatchNode {
                                    Value = obj.ToString().Replace("[[", "").Replace("]]", ""), Column = attr.Column, Line = attr.Line
                                });
                            }

                            foreach (var kitsuneObject in kitsuneObjects)
                            {
                                var objectPathArray = kitsuneObject.Value.ToLower().Split('.');
                                if (objectPathArray.Length > 1)
                                {
                                    var ind = 0;
                                    var basePropertyName = objectPathArray[ind];
                                    var baseEntity       = entities.Keys.Contains(basePropertyName) ? entities[basePropertyName] : null;

                                    if (baseEntity == null)
                                    {
                                        baseEntity = entities.First().Value;
                                        //result.Add(new CompilerError { Message = "Unrecognized Class of type '" + basePropertyName + "'", LineNumber = kitsuneObject.Line, LinePosition = kitsuneObject.Column });
                                        //continue;
                                    }


                                    var baseClassList = baseEntity.Classes.Where(x => x.ClassType == KClassType.BaseClass);

                                    var baseClass = baseClassList.FirstOrDefault(x => x.Name?.ToLower() == basePropertyName);

                                    if (baseClass != null)
                                    {
                                        result.AddRange(ValidateExpression(objectPathArray, ++ind, basePropertyName, PropertyType.obj, kitsuneObject.Line, kitsuneObject.Column, userEmail, baseEntity));
                                    }
                                    else if (!(basePropertyName.StartsWith("kresult") || basePropertyName.StartsWith("_system")))
                                    {
                                        result.Add(new CompilerError {
                                            Message = "Unrecognized Class of type '" + basePropertyName + "'", LineNumber = kitsuneObject.Line, LinePosition = kitsuneObject.Column
                                        });
                                    }
                                }
                            }
                        }
                    }


                    #endregion
                    index++;
                }
            }
            catch (Exception ex)
            {
            }
            return(result);
        }
Example #30
0
        public static async Task <KLMResponseModel> GetHtmlFromKlmAsync(RequestDetails request, string domainName, string url, string projectId = null,
                                                                        string schemeId   = null, string s3UrlForResource = null, string noCacheQueryParam = null, string developerId = null,
                                                                        string urlPattern = null, string websiteId        = null, Kitsune.Models.Project.KitsunePageType pageType = Kitsune.Models.Project.KitsunePageType.DEFAULT,
                                                                        KitsuneRequestUrlType kitsuneRequestUrlType = KitsuneRequestUrlType.PRODUCTION, string httpProtocol = "http://",
                                                                        List <Kitsune.Models.Project.ProjectComponent> components = null, string s3FolderUrl = null, string optimizedFilePath = null,
                                                                        string urlPatternRegex = null, int compilerVersion = 0, string fptag = null)
        {
            try
            {
                var tempVariableForCache = (!string.IsNullOrEmpty(noCacheQueryParam)) ? !(string.Compare(noCacheQueryParam, "true", true) == 0) : isKLMApiCacheEnabled;
                var functionLog = new Dictionary <string, long>(); var functionStopWatch = new Stopwatch();

                #region HTTP HEADER INFO

                var    ipAddress = request.IPAddress;
                string perfLog   = request.Perflog;

                #endregion

                functionStopWatch.Start();
                var websiteName = domainName.Split(',')[0];

                //if (isNFSite)
                //{
                //    var themeId = MongoHelper.GetThemeIdForUser(ipAddress, domainName);
                //    if (themeId != null)
                //    {
                //        projectId = themeId;
                //    }
                //}

                #region GET ENTITY INFO

                var entity = new KEntity();

                var EntityId = schemeId;
                //if (string.IsNullOrEmpty(EntityId))
                //{
                //    EntityId = "58d717e667962d6f40f5c198";
                //}
                if (tempVariableForCache && !string.IsNullOrEmpty(EntityId))
                {
                    entity = await CacheHelper.GetEntityInfoAsync(EntityId, tempVariableForCache);
                }

                if ((entity == null || entity.Classes == null) && !string.IsNullOrEmpty(EntityId))
                {
                    entity = await MongoHelper.GetLanguageEntityAsync(EntityId);

                    if (tempVariableForCache)
                    {
                        CacheHelper.SaveEntityInfo(EntityId, entity);
                    }
                }

                Helper.Helper.UpdateFunctionLog(functionLog, Helper.Constant.GETTING_ENTITY, functionStopWatch.ElapsedMilliseconds);

                var businessClass = Kitsune.Language.Helper.Helper.GetClassFromJson(entity);
                var auditLog      = new Kitsune.Models.KLMAuditLogModel();

                #endregion

                Helper.Helper.UpdateFunctionLog(functionLog, Helper.Constant.GETTING_HTTP_HEADER_INFO, functionStopWatch.ElapsedMilliseconds);
                functionStopWatch.Reset();

                //if (!string.IsNullOrEmpty(websiteName))
                //{
                #region WEBSITE DETAILS FROM CACHE

                functionStopWatch.Start();

                var requestUrl        = new Uri(url);
                var httpRequestObject = JsonConvert.DeserializeObject <Newtonsoft.Json.Linq.JObject>(JsonConvert.SerializeObject(new { url = requestUrl.AbsoluteUri, urlpath = requestUrl.AbsolutePath, urlsegments = requestUrl.Segments }));

                var  view = string.Empty; var viewDetails = new Models.Pagination();
                bool isDetailsView = false; var urlParamList = new Dictionary <string, string>(); bool isSearchView = false;
                var  queryString = string.Empty;

                // GET URL FROM API
                var rootaliasurl = String.Format("{0}{1}", httpProtocol, websiteName);
                if (!string.IsNullOrEmpty(s3UrlForResource) && !string.IsNullOrEmpty(projectId))
                {
                    isDetailsView = (pageType == Kitsune.Models.Project.KitsunePageType.DETAILS) ? true : false;
                    isSearchView  = (pageType == Kitsune.Models.Project.KitsunePageType.SEARCH) ? true : false;
                    bool isDefaultView = (pageType == Kitsune.Models.Project.KitsunePageType.DEFAULT) ? true : false;

                    var tempUrl = new Uri(url);
                    viewDetails = PaginationHelper.GetViewDetails(url.Trim('/'), urlPattern, rootaliasurl, isDetailsView, isSearchView);
                    if (isDetailsView)
                    {
                        queryString = Helper.Helper.GetQueryStringForDL(urlPattern);
                    }
                }
                if (string.IsNullOrEmpty(s3UrlForResource))
                {
                    return(null);
                }

                dynamic websiteData = null;
                //TODO: Need to stop backward compatibility.
                //if (compilerVersion != 1)
                //{
                //    var websiteDetails = CacheHelper.GetBusinessDetailsFromCache(websiteName, tempVariableForCache, domainName, isNFSite, businessClass, entity.EntityName, developerId, websiteId, EntityId == "5aa8ffd8942c3406a81d0d7c", null);
                //    websiteData = websiteDetails;
                //}

                // if (websiteData == null)
                // {
                websiteData = (Newtonsoft.Json.Linq.JToken)JsonConvert.DeserializeObject("{ _system:{}, rootaliasurl:{} }");
                //}

                websiteData["_system"]            = (Newtonsoft.Json.Linq.JToken)JsonConvert.DeserializeObject("{viewbag:{}}");
                websiteData["_system"]["request"] = httpRequestObject;
                if (!String.IsNullOrEmpty(websiteData?.rootaliasurl?.url?.Value))
                {
                    rootaliasurl = websiteData.rootaliasurl.url.Value;
                }
                else
                {
                    websiteData["rootaliasurl"] = (Newtonsoft.Json.Linq.JToken)JsonConvert.DeserializeObject($"{{ url :  '{rootaliasurl}'  }}");
                }

                websiteData["rootaliasurl"]["url"] = (rootaliasurl).ToLower();

                //Get Component
                //To be reviewed
                #region Component Data
                if (components != null && components.Any())
                {
                    try
                    {
                        websiteData["_system"]["components"] = ApiHelper.GetComponentsData(components, projectId, websiteId, url, s3FolderUrl, rootaliasurl, kitsuneRequestUrlType);
                    }
                    catch { }
                }
                #endregion

                Helper.Helper.UpdateFunctionLog(functionLog, Helper.Constant.GETTING_FP_DETAILS, functionStopWatch.ElapsedMilliseconds);
                functionStopWatch.Reset();

                #endregion

                #region GET HTML FROM URL
                functionStopWatch.Start();

                string htmlString;

                //TODO: Need to stop backward compatibility.
                //if (compilerVersion == 1)
                //{
                htmlString = Helper.Helper.GetHtmlStringFromUrl(s3UrlForResource + ".kc");
                //}
                //else
                //{
                //    htmlString = Helper.Helper.GetHtmlStringFromUrl(s3UrlForResource);
                //}
                KLMResponseModel klmResponse;
                if (string.IsNullOrEmpty(htmlString))
                {
                    klmResponse          = new KLMResponseModel();
                    klmResponse.HtmlCode = string.Empty;
                    return(klmResponse);
                }

                Helper.Helper.UpdateFunctionLog(functionLog, Helper.Constant.GET_HTML_FROM_URL, functionStopWatch.ElapsedMilliseconds);
                functionStopWatch.Reset();
                #endregion



                //if (compilerVersion == 1)
                //{
                byte[] bytes        = Convert.FromBase64String(htmlString);
                string stringValue  = System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);
                var    jsonsettings = new JsonSerializerSettings();
                jsonsettings.TypeNameHandling = TypeNameHandling.Auto;
                KitsunePage           page          = JsonConvert.DeserializeObject <KitsunePage>(stringValue, jsonsettings);
                BlockLevelKLMExecutor blklmexecutor = new BlockLevelKLMExecutor(entity, functionLog, page, viewDetails, rootaliasurl, websiteId, schemeId, url, urlPattern, urlPatternRegex, websiteData, fptag, kitsuneRequestUrlType == KitsuneRequestUrlType.PRODUCTION, developerId);
                functionStopWatch.Start();

                klmResponse         = blklmexecutor.Execute();
                klmResponse.PerfLog = functionLog;
                Helper.Helper.UpdateFunctionLog(functionLog, "New KLM Flow", functionStopWatch.ElapsedMilliseconds);
                functionStopWatch.Reset();

                //To be reviewed
                #region  CUSTOM SUPPORT FOR KAPP MODULES
                try
                {
                    string componentString = "";
                    if (components != null && components.Count > 0 && websiteData?._system?.components != null)
                    {
                        foreach (var component in components)
                        {
                            switch (component.ProjectId)
                            {
                            //RIA App ID
                            case "5ab5190ba35c3b04e9817cb5":
                            {
                                if (kitsuneRequestUrlType == KitsuneRequestUrlType.PRODUCTION && websiteData["components"]?["_" + component.SchemaId] != null)
                                {
                                    componentString += "<img src='http://www.google-analytics.com/collect?v=1&tid=UA-35051129-38&t=event&ec=" + websiteData["components"]["_" + component.SchemaId]["notif_type"] ?? "" + "&ea=open&el=" + websiteData["components"]["_" + component.SchemaId]["website_domain"] ?? "" + "&cs=newsletter&cm=email&cn=" + websiteData["components"]["_" + component.SchemaId]["project_id"] ?? "" + "&cm1=1&cd1=" + websiteData["components"]["_" + component.SchemaId]["recipient_email"] ?? "" + "&cid=" + websiteData["components"]["_" + component.SchemaId]["website_user_id"] ?? "" + "' style='z-index:-1; display: none; visibility: hidden; width:0px; height:0px;' />";
                                }
                                break;
                            }
                            }
                        }
                    }
                    componentString     += "</body>";
                    klmResponse.HtmlCode = klmResponse.HtmlCode.Replace("</body>", componentString);
                }
                catch { }
                #endregion
                //}
                //else
                //{
                //    var document = new HtmlDocument();
                //    htmlString = WebUtility.HtmlDecode(htmlString);
                //    document.LoadHtml(htmlString);

                //    #region  CUSTOM SUPPORT FOR KAPP MODULES
                //    try
                //    {
                //        if (components != null && components.Count > 0 && websiteData?._system?.components != null)
                //        {
                //            foreach (var component in components)
                //            {
                //                switch (component.ProjectId)
                //                {
                //                    //RIA App ID
                //                    case "5ab5190ba35c3b04e9817cb5":
                //                        {
                //                            try
                //                            {
                //                                if (kitsuneRequestUrlType == KitsuneRequestUrlType.PRODUCTION && websiteData["components"]["_" + component.SchemaId] != null)
                //                                {
                //                                    var tempKappNode = HtmlNode.CreateNode("<img src=\"http://www.google-analytics.com/collect?v=1&tid=UA-35051129-38&t=event&ec=[[_system.components._" + component.SchemaId + ".notif_type]]&ea=open&el=[[_system.components._" + component.SchemaId + ".website_domain]]&cs=newsletter&cm=email&cn=[[_system.components._" + component.SchemaId + ".project_id]]&cm1=1&cd1=[[_system.components._" + component.SchemaId + ".recipient_email]]&cid=[[_system.components._" + component.SchemaId + ".website_user_id]]\" style=\"z-index:-1; display: none; visibility: hidden; width:0px; height:0px;\" />");

                //                                    var tempBodyDocumentReference = document.DocumentNode.SelectSingleNode("//body");
                //                                    tempBodyDocumentReference.AppendChild(tempKappNode);
                //                                }
                //                            }
                //                            catch { }
                //                            break;
                //                        }
                //                }
                //            }
                //        }
                //        htmlString = document.DocumentNode.OuterHtml;
                //    }
                //    catch { }
                //    #endregion

                //    klmExecutor = new KLMExecutor(kitsuneRequestUrlType);
                //    htmlString = klmExecutor.Execute(websiteId, entity, websiteData, viewDetails, queryString, document, functionLog, isDetailsView, isNFSite);

                //    #region MINIFY HTML
                //    functionStopWatch.Start();
                //    try
                //    {
                //        //var minify = Uglify.Html(htmlString, new NUglify.Html.HtmlSettings() { DecodeEntityCharacters = false, KeepOneSpaceWhenCollapsing = true });
                //        NUglify.Html.HtmlSettings settings = new NUglify.Html.HtmlSettings() { DecodeEntityCharacters = false, RemoveOptionalTags = false, ShortBooleanAttribute = false };
                //        //settings.TagsWithNonCollapsableWhitespaces.Add("p", false);
                //        var minify = Uglify.Html(htmlString, settings);
                //        htmlString = minify.Code;
                //    }
                //    catch (Exception ex)
                //    {
                //        //TODO: Log Error while minifing html
                //    }
                //    finally
                //    {
                //        functionStopWatch.Stop();
                //        Helper.Helper.UpdateFunctionLog(functionLog, Helper.Constant.MINIFICATION, functionStopWatch.ElapsedMilliseconds);
                //        functionStopWatch.Reset();
                //    }
                //    klmResponse = new KLMResponseModel();
                //    klmResponse.HtmlCode = htmlString;
                //    klmResponse.CacheableResult = true;
                //    klmResponse.PerfLog = functionLog;
                //    #endregion
                //}

                Helper.Helper.UpdateFunctionLog(functionLog, "update custom component modules", functionStopWatch.ElapsedMilliseconds);
                functionStopWatch.Reset();

                #region UPDATE LOG

                auditLog = new KLMAuditLogModel()
                {
                    _id = ObjectId.GenerateNewId().ToString(), city = null, country = null, createdOn = DateTime.UtcNow, functionalLog = functionLog, fpTag = websiteName, ipAddress = ipAddress, themeId = projectId, loadTime = functionStopWatch.Elapsed.Seconds
                };
                KinesisHelper.LogKLMRequestDetailsIntoKinesis(auditLog, url);

                #endregion

                klmResponse.HtmlCode = klmResponse.HtmlCode.Replace("[LOG_ID]", auditLog._id);
                klmResponse.HtmlCode = klmResponse.HtmlCode.Replace("[KITSUNE_WEBSITE_ID]", websiteId);

                if (perfLog != null && perfLog?.ToLower() == "true")
                {
                    klmResponse.HtmlCode += "\nPerf extract:\n";
                    foreach (string key in functionLog.Keys)
                    {
                        klmResponse.HtmlCode += key + " : " + functionLog[key] + "\n";
                    }
                }
                return(klmResponse);
                //}
            }
            catch (Exception ex)
            {
                throw;
                //return ex.Message + ex.StackTrace;
            }

            return(null);
        }