public void SimpleDataTest() { //TTODO: test repeat within multiple deep collection merge e.g. c{d(e)}, c{d(g)} => c{d(e,g)} _config.Logger = _logs; _config.EscapePrefix = "\\"; var parser = new TemplatorParser(_config); foreach (var entry in GetSimpleDataEntries()) { parser.StartOver(); _logs.Errors.Clear(); if (entry.IsXml) { parser.ParseXml(entry.Xml, entry.Input); } else if (entry.IsCsv) { parser.ParseCsv(entry.Template, entry.Input); } else { parser.ParseText(entry.Template, entry.Input); } Assert.AreEqual(entry.FieldCount, parser.Holders.Count); if (_logs.Errors.Count > 0) { var errors = _logs.Errors.Select(i => i.Message).Join("$$"); Assert.AreEqual(entry.Log, errors); } else { Assert.IsTrue(entry.Log.IsNullOrEmpty()); if (entry.IsXml) { Assert.IsTrue(XNode.DeepEquals(entry.XmlOutput, parser.XmlContext.Element)); } else { Assert.AreEqual(entry.Output, parser.Context.Result.ToString()); } } if (!entry.Levels.IsNullOrEmpty()) { var fields = parser.Holders; foreach (var s in entry.Levels.Split(',')) { Assert.IsTrue(fields.ContainsKey(s)); fields = fields[s].Children; } } } }
public void GenerateDoc() { const string docPath = "../../../../doc/"; var config = TemplatorConfig.DefaultInstance; config.XmlTemplatorAttributeName = "bindings"; var parser = new TemplatorParser(config); var stream = "DocGenerate.Resources.index.html".GetResourceStreamFromExecutingAssembly(); var input = TemplatorHelpDoc.GetInputDict(docPath); var outPut = parser.LoadXmlTemplate(stream, input); using (var sw = new StreamWriter(docPath + "index.html", false)) { sw.Write(outPut); } if (((TemplatorLogger)config.Logger).Errors.Count > 0) { Assert.Fail(((TemplatorLogger)config.Logger).Errors.First().Message); } config = TemplatorConfig.DefaultInstance; config.CustomOptions = new[] { new TemplatorConfig.TemplatorCustomerConfigEntry() { Category = "SyntaxBuildTask", Key = "Filters", Value = ".xml,.csv,.txt" }, new TemplatorConfig.TemplatorCustomerConfigEntry() { Category = "SyntaxBuildTask", Key = "Path", Value = "Templates" }, new TemplatorConfig.TemplatorCustomerConfigEntry() { Category = "SyntaxBuildTask", Key = "Depth", Value = "3" }, }; config.CustomKeywordNames = new[] { "AnotherKeywordName" }; using (var sw = new StreamWriter(docPath + "TemplatorConfig.xml", false)) { sw.Write(config.ToXElement().ToString()); } }
private void BuildReference() { var project = _dte.ActiveDocument.ProjectItem.ContainingProject; string projectName = null; if (project != null) { if (_activeProjectName != project.FullName) { if (!_parsers.ContainsKey(project.FullName)) { ProjectItem doc = null; for (var i = 1; i <= project.ProjectItems.Count; i++) { doc = project.ProjectItems.Item(i); if (doc.Name == TemplatorConfigFileName) { break; } doc = null; } if (doc != null) { if (_documentEvents.ContainsKey(project.FullName)) { _documentEvents[project.FullName].DocumentSaved -= Document_Changed; _documentEvents.Remove(project.FullName); } var de = doc.DTE.Events.DocumentEvents; _documentEvents.AddOrOverwrite(project.FullName, de); de.DocumentSaved -= Document_Changed; de.DocumentSaved += Document_Changed; var config = TryGeTemplatorConfig(doc); if (config != null) { config.ContinueOnError = true; config.OnTokenFound = OnTemplatorTokenFound; _parsers.AddOrOverwrite(project.FullName, new TemplatorParser(config)); } } } } projectName = project.FullName; } else { _activeProjectName = null; } if (_activeProjectName != projectName || (_dte.ActiveDocument.Name == TemplatorConfigFileName) == (_parser != null)) { lock (LockObject) { _parser = _dte.ActiveDocument.Name == TemplatorConfigFileName ? null : projectName == null ? null : _parsers.GetOrDefault(projectName); } } _activeProjectName = projectName; if (_buildDefaultConfig) { if (_dte?.Solution != null) { _solutionEvents = _dte.Solution.DTE.Events.SolutionItemsEvents; _solutionEvents.ItemAdded -= SolutionItemsEvents_ItemChanged; _solutionEvents.ItemAdded += SolutionItemsEvents_ItemChanged; _solutionEvents.ItemRemoved -= SolutionItemsEvents_ItemChanged; _solutionEvents.ItemRemoved += SolutionItemsEvents_ItemChanged; _solutionEvents.ItemRenamed -= SolutionItemsEventsOnItemRenamed; _solutionEvents.ItemRenamed += SolutionItemsEventsOnItemRenamed; _buildDefaultConfig = false; } } }
public override bool Execute() { var msg = new BuildMessageEventArgs("Templator Syntax checking", "", "TemplatorSyntaxChecker", MessageImportance.Normal); BuildEngine.LogMessageEvent(msg); if (ConfigFilePath.IsNullOrWhiteSpace()) { var proj = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(ProjectPath).FirstOrDefault() ?? new Project(ProjectPath); var configFile = proj.GetItemsByEvaluatedInclude(TemplatorConfig.DefaultConfigFileName).FirstOrDefault(); if (configFile != null) { ConfigFilePath = configFile.EvaluatedInclude; } } TemplatorConfig config; if (ConfigFilePath.IsNullOrWhiteSpace()) { config = TemplatorConfig.DefaultInstance; const string url = "https://github.com/djsxp/Templator/blob/master/project/Templator/TemplatorConfig.xml"; msg = new BuildMessageEventArgs("Unable to find '{0}', using defaults, for a config file, please find; '{1}'".FormatInvariantCulture(TemplatorConfig.DefaultConfigFileName, url), "", "TemplatorSyntaxChecker", MessageImportance.Normal); BuildEngine.LogMessageEvent(msg); } else { try { config = TemplatorConfig.FromXml(ConfigFilePath); var path = config.CustomOptions.EmptyIfNull().PropertyOfFirstOrDefault(c => c.Category == ConfigCategory && c.Key == "Path", pr => pr.Value); Path = path ?? Path; var filter = config.CustomOptions.EmptyIfNull().PropertyOfFirstOrDefault(c => c.Category == ConfigCategory && c.Key == "Filters", pr => pr.Value); Filters = filter ?? Filters; var depth = config.CustomOptions.EmptyIfNull().PropertyOfFirstOrDefault(c => c.Category == ConfigCategory && c.Key == "Depth", pr => pr.Value); int d; Depth = int.TryParse(depth, out d) ? d : Depth; } catch (Exception e) { var message = new BuildErrorEventArgs("TemplatorSyntaxConfig", "TemplatorConfigLoadError", ConfigFilePath, 0, 0, 0, 0, e.Message, "TemplatorBuildTask", "TemplatorBuildTask"); BuildEngine.LogErrorEvent(message); return(false); } } if (Path.IsHtmlNullOrWhiteSpace() || !Directory.Exists(Path)) { var message = new BuildErrorEventArgs("TemplatorSyntaxConfig", "Unable to find the template path: '{0}'".FormatInvariantCulture(Path), "project", 0, 0, 0, 0, "", "TemplatorBuildTask", "TemplatorBuildTask"); BuildEngine.LogErrorEvent(message); return(false); } string[] filters = null; if (!Filters.IsNullOrWhiteSpace()) { filters = Filters.Split(','); } var logger = new TemplatorLogger(); config.Logger = logger; var p = new TemplatorParser(config); p.GrammarCheckDirectory(Path, filters, Depth); if (p.ErrorCount > 0) { foreach (var m in logger.Errors) { var message = new BuildErrorEventArgs("TemplatorSyntaxChecker", "TemplatorSyntaxError", m.FileName, m.Line + 1, m.Column + 1, m.EndLineNumber + 1, m.EndColumnNumber + 1, m.Message, "TemplatorBuildTask", "TemplatorBuildTask"); BuildEngine.LogErrorEvent(message); } } return(p.ErrorCount == 0); }
public void MapInput() { const string tem = @" {{Data(Field1)}} {{Data(Employers)[Collection]}} {{(FirstName)}} {{Calculated(Wages)}}, {{Data(PaymentAmount)}}, {{Data(Months)}}, {{Data(Employees)[Collection]}} {{User(Index)}}, {{User(Custom)}}, {{User(Wages)}}, {{(FirstName)}} {{Data(Employment)[Collection]}} {{(FirstName)}} {{Data(Employment)[CollectionEnd]}} {{Data(Employees)[CollectionEnd]}} {{Data(Employers)[CollectionEnd]}} {{Data(Field2)}}"; var parser = new TemplatorParser(TemplatorConfig.DefaultInstance); parser.ParseText(tem, null); //Get the holder definitions var fields = parser.Holders; //initialize a config instance var config = new TemplatorInputMapper <TestContext>(); //map for names, config.AddNameResolver("Employers") .AsCollectionContext() //for collections, resolve as a collection of child contexts .ResolveAs(new List <TestContext> { new TestContext() { Company = new Company() { Name = "C1", Employees = new List <Employee>() { new Employee() { FirstName = "C1E1" }, new Employee() { FirstName = "C1E2" } } } } }); config.AddNameResolver("Employees").AsCollectionContext() //resolve as a collection of contexts, set context's references at this point .ResolveAs((holder, context) => { return(context.Company?.Employees?.Select(e => new TestContext() { CurrentEmployee = e, Company = context.Company }).ToArray()); }); config.AddNameResolver("Employment").AsCollectionContext().ResolveAs((holder, context) => (new TestContext() { CurrentEmployee = context.CurrentEmployee }).Single()); //Simple name resolver config.AddNameResolver("Field1").ResolveAs("(HolderValueField1)"); //Resolve by category with inner logic config.AddCategoryResolver("Calculated").ResolveAs((holder, context) => { var c = context.Root.Input["Calculated"]; return(c); }); config.AddNameResolver("Wages").ResolveAs("WillNeedToShow"); //Resolve by hierarchy config.AddHierarchyResolver("Employers.Employees").ResolveAs("Employers.Employees"); //Customized matching config.AddCustomResolver().MatchWith((holder, context) => context.CurrentEmployee != null && holder.Name == "Custom").ResolveAs("CustomResoved"); //Retrieve collection items' indexes config.AddNameResolver("Index").ResolveAs((holder, context) => context.CollectionIndex); //Resolve by name and match only in specific level config.AddNameResolver("FirstName").SpecifyHierarchies("Employers.Employees.Employment").ResolveAs((holder, context) => context.CurrentEmployee.FirstName); config.AddNameResolver("FirstName") //Retrieve context values .ResolveAs((holder, context) => context.Company.Name); config.AddCategoryResolver("User").ResolveAs("UserField"); config.AddCategoryResolver("Data").ResolveAs("DataField"); //Set a default resolver config.SetDefaultResolver((holder, context) => holder.Name); //it is recommended to create a new instance for processing from the config instance, rather than use the config instance to process //for better maintenance as well as thread safety var mapper = new TemplatorInputMapper <TestContext>(config) { Logger = new TemplatorLogger() };; //enable resolvers in priority order mapper.EnableNameResolvers(); mapper.EnableCategoryResolvers(); mapper.EnableHierachyResolvers(); mapper.EnableCustomResolvers(); var input = mapper.GenerateInput(fields, new TestContext() { Input = new Dictionary <string, object>() { { "Calculated", 1 } } }); Assert.IsTrue(mapper.Logger.IsEmpty()); parser.StartOver(); var parsed = parser.ParseText(tem, input); Assert.AreEqual(@" (HolderValueField1) C1 WillNeedToShow, DataField, DataField, 0, UserField, WillNeedToShow, C1 C1E1 1, UserField, WillNeedToShow, C1 C1E2 DataField", parsed); }
public string ParseDacpac(string dacpacFileName) { try { if (!Enabled) { return(null); } if (!File.Exists(dacpacFileName) && !ErrorIfDacpacNotFound) { return(null); } using (var stream = File.OpenRead(dacpacFileName)) { using (var zip = new ZipArchive(stream, ZipArchiveMode.Read)) { var modelEntry = zip.GetEntry("model.xml"); using (var entryStream = modelEntry.Open()) { var xml = XDocument.Load(entryStream); if (xml.Root == null) { return(null); } foreach (var x in xml.Root.DescendantsAndSelf()) { x.Name = x.Name.LocalName; x.ReplaceAttributes((from xattrib in x.Attributes().Where(xa => !xa.IsNamespaceDeclaration) select new XAttribute(xattrib.Name.LocalName, xattrib.Value))); } var entities = Entity.GetEntities(xml.Root, this).ToList(); var methods = Method.GetMethods(xml.Root, this, entities).ToList(); var config = TemplatorConfig.DefaultInstance; var parser = new TemplatorParser(config); foreach (var templatorKeyword in SqlToCsharpHelper.GetCustomizedTemplatorKeyword(this)) { config.Keywords.AddOrOverwrite(templatorKeyword.Name, templatorKeyword); } if (!Directory.Exists(ModelOutPath)) { Directory.CreateDirectory(ModelOutPath); } if (!Directory.Exists(DalOutPath)) { Directory.CreateDirectory(DalOutPath); } var template = GetTemplate(Entity.Template); foreach (var entity in entities) { var fileName = FileNameExtensionPrefix.IsNullOrWhiteSpace() ? entity.Name + ".cs" : "{0}.{1}.cs".FormatInvariantCulture(entity.Name, FileNameExtensionPrefix); var json = JsonConvert.SerializeObject(entity); var input = json.ParseJsonDict(); input.Add("Namespace", ModelNamespace); input.Add("Usings", Usings.EmptyIfNull().Select(u => new Dictionary <string, object>() { { "Using", u } }).Cast <object>().ToArray()); var file = parser.ParseText(template, input); parser.StartOver(); using (var sw = new StreamWriter(Path.Combine(ModelOutPath, fileName))) { sw.Write(file); } } template = GetTemplate(Method.Template); var iTemplate = GetTemplate(Method.InterfaceTemplate); var name = FileNameExtensionPrefix.IsNullOrWhiteSpace() ? DataAccessClassName + ".cs" : "{0}.{1}.cs".FormatInvariantCulture(DataAccessClassName, FileNameExtensionPrefix); using (var sw = new StreamWriter(Path.Combine(DalOutPath, name))) { using (var isw = new StreamWriter(Path.Combine(DalOutPath, "I" + name))) { var json = JsonConvert.SerializeObject(new { NonQueryMethods = methods.Where(m => m.IdentityColumns.IsNullOrEmpty() && m.Unique), ScalarMethods = methods.Where(m => !m.IdentityColumns.IsNullOrEmpty()), UniqueMethods = methods.Where(m => m.Unique), MultipleMethods = methods.Where(m => !m.Unique), InlineTableFunctions = StoredProcedure.GetInlineTableValuedFunctions(xml.Root, this), TableFunctions = StoredProcedure.GetlMultiStatementTableValuedFunctions(xml.Root, this), ScalarFunctions = StoredProcedure.GetScalarFunctions(xml.Root, this), Sps = StoredProcedure.GetStoredProcedures(xml.Root, this), }); var input = json.ParseJsonDict(); input.Add("DataAccessClassName", DataAccessClassName); input.Add("DalNamespace", DalNamespace); input.Add("HelperVersion", "1.0.0.4"); input.Add("Namespace", ModelNamespace); input.Add("ClassAccess", ClassAccess ?? "public"); input.Add("Usings", Usings.EmptyIfNull().Select(u => new Dictionary <string, object>() { { "Using", u } }).Cast <object>().ToArray()); var file = parser.ParseText(template, input); parser.StartOver(); sw.Write(file); file = parser.ParseText(iTemplate, input); parser.StartOver(); isw.Write(file); } } } } } } catch (Exception) { return("Unexpected Error while generating code. " + ConfigErrorMessage); } return(null); }