/// <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); } }
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()); } } }
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)); } }
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; } }
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); }
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); } } }
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); }
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); }
/// <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()); } }
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); }
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]); }
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); }
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); }