예제 #1
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);
        }
예제 #2
0
        public static CompilerError ValidatePartialView(ref string expression, List <ResourceItemMeta> resources)
        {
            var pageClassResult = Helper.Constants.PartialPageRegularExpression.Matches(expression);

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

                        if (!resources.Any(x => x.PageType == Models.Project.KitsunePageType.PARTIAL && x.SourcePath.ToLower() == viewName.ToLower()))
                        {
                            return(CompileResultHelper.GetCompileError(string.Format(ErrorCodeConstants.UnrecognizedView, viewName)));
                        }
                    }
                }
            }
            return(null);
        }
        /// <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);
                    }
                }
            }
        }
        /// <summary>
        /// Validate objects used in expressions are valid.
        /// </summary>
        /// <param name="compileErrors"></param>
        /// <param name="kentity"></param>
        /// <param name="objectNamesValidated"></param>
        /// <param name="classNameAlias"></param>
        /// <param name="baseClassList"></param>
        /// <param name="node"></param>
        private void ValidateExpressions(List <CompilerError> compileErrors, Dictionary <string, KEntity> entities, Dictionary <string, bool> objectNamesValidated, Dictionary <string, string> classNameAlias, IEnumerable <KClass> baseClassList, HtmlNode node, List <MatchNode> objectNamesToValidate, Dictionary <string, int> customVariables, GetProjectDetailsResponseModel projectDetails)
        {
            if (node.NodeType != HtmlNodeType.Element)
            {
                return;
            }
            int           lineNo           = 0;
            CompilerError viewExist        = null;
            CompilerError partialViewExist = null;
            string        viewExpression   = string.Empty;

            foreach (string line in node.OuterHtml.Split("\n"))
            {
                List <MatchNode> expressionNodes = HtmlHelper.GetExpressionFromElement(line, node.Line + lineNo);
                foreach (var expression in expressionNodes)
                {
                    try
                    {
                        viewExpression = expression.Value;
                        //View() function validation

                        viewExist = KitsuneCompiler.ValidateView(ref viewExpression, entities.First().Value);
                        if (viewExist != null)
                        {
                            viewExist.LineNumber   = expression.Line;
                            viewExist.LinePosition = expression.Column;
                            compileErrors.Add(viewExist);
                        }
                        //Partial() view function validation
                        partialViewExist = KitsuneCompiler.ValidatePartialView(ref viewExpression, projectDetails.Resources);
                        if (partialViewExist != null)
                        {
                            partialViewExist.LineNumber   = expression.Line;
                            partialViewExist.LinePosition = expression.Column;
                            compileErrors.Add(partialViewExist);
                        }

                        foreach (string raw_obj in Parser.GetObjects(viewExpression))
                        {
                            string obj = raw_obj.Replace("[[", "").Replace("]]", "").ToLower();
                            if (customVariables.ContainsKey(obj))
                            {
                                continue;
                            }
                            else
                            {
                                objectNamesToValidate.Add(new MatchNode {
                                    Value = obj, Line = node.Line + lineNo, Column = line.IndexOf(obj)
                                });
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        compileErrors.Add(CompileResultHelper.GetCompileError(ex.Message, node.Line, node.LinePosition));
                        continue;
                    }
                }
                lineNo++;
            }
            foreach (MatchNode obj in objectNamesToValidate)
            {
                Boolean isAlias    = false;
                string  objectName = obj.Value.ToLower();
                if ((classNameAlias.ContainsKey(objectName) && classNameAlias[objectName] == "") || customVariables.ContainsKey(objectName))
                {
                    continue;
                }
                string baseClassName = objectName.Split('.')[0];
                while (baseClassName != "kresult" && baseClassName != "search" && classNameAlias.ContainsKey(baseClassName))
                {
                    int index = objectName.IndexOf('.');
                    objectName    = classNameAlias[baseClassName] + (index >= 0 ? objectName.Substring(index) : "");
                    isAlias       = true;
                    baseClassName = objectName.Split('.')[0];
                }
                if (objectNamesValidated.ContainsKey(objectName))
                {
                    if (!objectNamesValidated[objectName] && !isAlias)
                    {
                        compileErrors.Add(CompileResultHelper.GetCompileError(String.Format(ErrorCodeConstants.UnrecognizedType, objectName), obj.Line, obj.Column));
                    }
                }
                else
                {
                    string[] objectPathArray  = objectName.ToLower().Split('.');
                    string   basePropertyName = objectPathArray[0];
                    var      baseClass        = baseClassList.FirstOrDefault(x => x.Name?.ToLower() == basePropertyName);

                    if (baseClass != null)
                    {
                        var baseEntity = entities.Keys.Contains(basePropertyName) ? entities[basePropertyName] : null;

                        if (baseEntity == null)
                        {
                            baseEntity = entities.First().Value;
                        }

                        IEnumerable <CompilerError> errorList = ValidateExpression(objectPathArray, 1, basePropertyName, PropertyType.obj, obj.Line, obj.Column, baseEntity);
                        if (errorList.Count() > 0)
                        {
                            compileErrors.AddRange(errorList);
                            objectNamesValidated.Add(objectName, false);
                        }
                        else
                        {
                            objectNamesValidated.Add(objectName, true);
                        }
                    }
                    else if (!ValidObjects.Contains(basePropertyName.Trim('[').Trim(']')) && ((basePropertyName.StartsWith("kresult") && !classNameAlias.ContainsKey("kresult")) || !basePropertyName.StartsWith("kresult")))
                    {
                        compileErrors.Add(CompileResultHelper.GetCompileError(String.Format(ErrorCodeConstants.UnrecognizedClass, basePropertyName), obj.Line, obj.Column));
                        //objectNamesValidated.Add(objectName, false);
                    }
                }
            }
            //InnerText returns text from inner html tags, need to clear so we don't run parser again. DOM is unaffected by this.
            node.InnerHtml = "";
            objectNamesToValidate.Clear();
        }
예제 #5
0
        public static CompileResult CompileHTML(CompileResourceRequest req, out HtmlDocument documentRef,
                                                GetProjectDetailsResponseModel projectDetails,
                                                KEntity kentity,
                                                GetPartialPagesDetailsResponseModel partialPages = null, bool subsequentCompilation = false, List <KLanguageModel> componentEntities = null) // partialPage is required only for the publish/preview
        {
            ///TODO : Handle the kitsune-settings.xml saperatly
            documentRef = GetDocumentObject();
            var filePath = req.SourcePath.Trim('/');

            if (!string.IsNullOrEmpty(req.FileContent))
            {
                HtmlDocument             document;
                List <CompilerError>     nfUXErrors      = new List <CompilerError>();
                Dictionary <string, int> customVariables = new Dictionary <string, int>();
                string rootUrl;

                DocumentPreprocessor.PreprocessDocument(req, kentity, filePath, out document, nfUXErrors, out rootUrl);
                documentRef = document;

                /*
                 * if (document.ParseErrors.Count() > 0)
                 * {
                 *  return CompileResultHelper.GetCompileResult(nfUXErrors, req.SourcePath, false);
                 * }
                 */
                req.UrlPattern = req.SourcePath; //assigning default urlpattern

                if (!req.IsStatic)
                {
                    if (kentity == null)
                    {
                        return(CompileResultHelper.GetErrorCompileResult("Schema not found for this project.", req.SourcePath));
                    }
                    else if (kentity.EntityName == null)
                    {
                        kentity.EntityName = Constants.KPayDefaultSchema;
                    }

                    HtmlDocument documentClone = GetDocumentObject();
                    documentClone.LoadHtml(document.DocumentNode.OuterHtml);
                    DocumentValidator validator = new DocumentValidator();
                    validator.ValidateDocument(documentClone, req, nfUXErrors, kentity, customVariables, rootUrl, filePath, projectDetails, componentEntities?.Select(x => x.Entity)?.ToList());
                    if (nfUXErrors.Count == 0)
                    {
                        if (req.IsPublish)
                        {
                            var csrfPresent = Constants.CSRFRegularExpression.IsMatch(document.DocumentNode.OuterHtml);

                            UpdateForPublish(ref document, req, kentity, nfUXErrors, customVariables, projectDetails, partialPages, componentEntities, csrfPresent);

                            if (req.PageType != Models.Project.KitsunePageType.PARTIAL)
                            {
                                HandleScriptInjection(document, req, kentity, rootUrl, projectDetails, csrfPresent);
                            }
                        }
                    }

                    /*
                     * KitsunePage myPage = (new NewRootNodeProcessor()).Process(document.DocumentNode.OuterHtml);
                     * var jsonSerializeSettings = new JsonSerializerSettings();
                     * jsonSerializeSettings.TypeNameHandling = TypeNameHandling.Objects;
                     * string output = JsonConvert.SerializeObject(myPage, Formatting.None, jsonSerializeSettings);
                     * //KitsunePage myNewPage = JsonConvert.DeserializeObject<KitsunePage>(output, jsonSerializeSettings);
                     */
                }
                UpdatePathsForPreview(req, document);
                if (nfUXErrors.Count > 0)
                {
                    return new CompileResult {
                               Success = false, ErrorMessages = nfUXErrors, PageName = req.SourcePath
                    }
                }
                ;
                else
                {
                    return new CompileResult {
                               Success = true, CompiledString = document.DocumentNode.OuterHtml.ToString(), ErrorMessages = nfUXErrors, PageName = req.SourcePath, CustomVariables = customVariables
                    }
                };
            }

            return(new CompileResult
            {
                Success = false,
                ErrorMessages = new List <CompilerError> {
                    new CompilerError {
                        Message = "Input should not be empty"
                    }
                },
                PageName = req.SourcePath,
            });
        }