/// <summary> /// insert the data into an Xml Node. This is useful for later converting the Xml to meaningful CSV with the same columns for Excel or Calc /// </summary> /// <param name="AJsonData"></param> /// <param name="ANode"></param> /// <param name="ADoc"></param> /// <param name="AOverwrite"></param> public static void DataToXml(string AJsonData, ref XmlNode ANode, XmlDocument ADoc, bool AOverwrite) { if (AJsonData.Length == 0) { return; } try { string RequiredCulture = CultureInfo.CurrentCulture.Name; AJsonData = RemoveContainerControls(AJsonData, ref RequiredCulture); JsonObject list = (JsonObject)JsonConvert.Import(AJsonData); foreach (string key in list.Names) { if (AOverwrite || !TXMLParser.HasAttribute(ANode, key)) { XmlAttribute attr = ADoc.CreateAttribute(StringHelper.UpperCamelCase(key)); string text = list[key].ToString().Replace("<br/>", "_"); attr.Value = text; ANode.Attributes.Append(attr); } } } catch (Exception) { TLogging.Log("Problem parsing: " + AJsonData); throw; } }
/// <summary> /// format the XML into CSV so that it can be opened as a spreadsheet; /// this only works for quite simple files; /// hierarchical structures are flattened (using childOf column) /// </summary> public static string Xml2CsvString(XmlDocument ADoc) { // first write the header of the csv file List <string> AllAttributes = new List <string>(); List <XmlNode> AllNodes = new List <XmlNode>(); GetAllAttributesAndNodes(ADoc.DocumentElement, ref AllAttributes, ref AllNodes); string separator = TAppSettingsManager.GetValue("CSVSeparator", System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator); string headerLine = ""; foreach (string attrName in AllAttributes) { if (headerLine.Length > 0) { headerLine += separator; } headerLine += "\"" + attrName + "\""; } string result = headerLine + Environment.NewLine; foreach (XmlNode node in AllNodes) { string line = ""; foreach (string attrName in AllAttributes) { if (attrName == "childOf") { line = StringHelper.AddCSV(line, TXMLParser.GetAttribute(node.ParentNode, "name"), separator); } else { line = StringHelper.AddCSV(line, TXMLParser.GetAttribute(node, attrName), separator); } } result += line + Environment.NewLine; } return(result); }
/// <summary> /// find a node somewhere in the xml document by its tag name and attribute name /// </summary> /// <param name="AParentNode"></param> /// <param name="ANodeNameToSearch"></param> /// <param name="ANameAttribute"></param> /// <returns></returns> public static XmlNode FindNodeRecursive(XmlNode AParentNode, string ANodeNameToSearch, string ANameAttribute) { for (Int32 counter = 0; counter < AParentNode.ChildNodes.Count; counter++) { XmlNode ChildNode = AParentNode.ChildNodes[counter]; if (ChildNode.Name == ANodeNameToSearch) { if (ANameAttribute.Length > 0) { if (TXMLParser.HasAttribute(ChildNode, "name") && (TXMLParser.GetAttribute(ChildNode, "name") == ANameAttribute)) { return(ChildNode); } } else { return(ChildNode); } } } XmlNode ResultNode = GetChild(AParentNode, ANodeNameToSearch); if (ResultNode == null) { foreach (XmlNode childNode in AParentNode.ChildNodes) { ResultNode = FindNodeRecursive(childNode, ANodeNameToSearch, ANameAttribute); if (ResultNode != null) { return(ResultNode); } } } if (ANameAttribute.Length > 0) { return(null); } return(ResultNode); }
/// <summary> /// convert a CSV file to an XmlDocument. /// the first line is expected to contain the column names/captions, in quotes. /// from the header line, the separator can be determined, if the parameter ASeparator is empty /// </summary> public static XmlDocument ParseCSV2Xml(List <string> ALines, string ASeparator = null) { XmlDocument myDoc = TYml2Xml.CreateXmlDocument(); int LineCounter = 1; string headerLine = ALines[0]; string separator = ASeparator; if (string.IsNullOrEmpty(ASeparator)) { if (!headerLine.StartsWith("\"")) { throw new Exception(Catalog.GetString("Cannot open CSV file, because it is missing the header line.") + Environment.NewLine + Catalog.GetString("There must be a row with the column captions, at least the first caption must be in quotes.")); } else { // read separator from header line. at least the first column needs to be quoted separator = headerLine[StringHelper.FindMatchingQuote(headerLine, 0) + 2].ToString(); } } List <string> AllAttributes = new List <string>(); while (headerLine.Length > 0) { string attrName = StringHelper.GetNextCSV(ref headerLine, separator); if (attrName.Length == 0) { TLogging.Log("Csv2Xml: found empty column header, will not consider any following columns"); break; } if (attrName.Length > 1) { attrName = attrName[0] + StringHelper.UpperCamelCase(attrName, ' ', false, false).Substring(1); } // some characters are not allowed in the name of an XmlAttribute attrName = attrName.Replace("%", "percent"); attrName = attrName.Replace("-", "hyphen"); attrName = attrName.Replace("/", "slash"); attrName = attrName.Replace(" ", "space"); try { myDoc.CreateAttribute(attrName); } catch (Exception) { char[] arr = attrName.ToCharArray(); // filter only letters and digits arr = Array.FindAll <char>(arr, (c => (char.IsLetterOrDigit(c)))); attrName = new string(arr); } AllAttributes.Add(attrName); } LineCounter = 1; while (LineCounter < ALines.Count) { string line = ALines[LineCounter]; if (line.Trim().Length > 0) { SortedList <string, string> AttributePairs = new SortedList <string, string>(); foreach (string attrName in AllAttributes) { // support csv values that contain line breaks AttributePairs.Add(attrName, StringHelper.GetNextCSV(ref line, ALines, ref LineCounter, separator)); } string rowName = "Element"; if (AttributePairs.ContainsKey("name")) { rowName = AttributePairs["name"]; } XmlNode newNode = myDoc.CreateElement("", rowName, ""); if (AttributePairs.ContainsKey("childOf")) { XmlNode parentNode = TXMLParser.FindNodeRecursive(myDoc.DocumentElement, AttributePairs["childOf"]); if (parentNode == null) { parentNode = myDoc.DocumentElement; } parentNode.AppendChild(newNode); } else { myDoc.DocumentElement.AppendChild(newNode); } foreach (string attrName in AllAttributes) { if ((attrName != "name") && (attrName != "childOf")) { XmlAttribute attr = myDoc.CreateAttribute(attrName); attr.Value = AttributePairs[attrName]; newNode.Attributes.Append(attr); } } } LineCounter++; } return(myDoc); }
/// <summary> /// store the data into Excel format, Open Office XML, .xlsx /// /// this makes use of the EPPlus library /// http://epplus.codeplex.com/ /// </summary> private static void Xml2ExcelWorksheet(XmlDocument ADoc, ExcelWorksheet AWorksheet, bool AWithHashInCaption = true) { Int32 rowCounter = 1; Int16 colCounter = 1; // first write the header of the csv file List <string> AllAttributes = new List <string>(); List <XmlNode> AllNodes = new List <XmlNode>(); GetAllAttributesAndNodes(ADoc.DocumentElement, ref AllAttributes, ref AllNodes); foreach (string attrName in AllAttributes) { if (AWithHashInCaption) { AWorksheet.Cells[rowCounter, colCounter].Value = "#" + attrName; } else { AWorksheet.Cells[rowCounter, colCounter].Value = attrName; } colCounter++; } rowCounter++; colCounter = 1; foreach (XmlNode node in AllNodes) { foreach (string attrName in AllAttributes) { if (attrName == "childOf") { AWorksheet.Cells[rowCounter, colCounter].Value = TXMLParser.GetAttribute(node.ParentNode, "name"); } else { string value = TXMLParser.GetAttribute(node, attrName); if (value.StartsWith(eVariantTypes.eDateTime.ToString() + ":")) { AWorksheet.Cells[rowCounter, colCounter].Value = TVariant.DecodeFromString(value).ToDate(); AWorksheet.Cells[rowCounter, colCounter].Style.Numberformat.Format = "dd/mm/yyyy"; } else if (value.StartsWith(eVariantTypes.eInteger.ToString() + ":")) { AWorksheet.Cells[rowCounter, colCounter].Value = TVariant.DecodeFromString(value).ToInt64(); } else if (value.StartsWith(eVariantTypes.eDecimal.ToString() + ":")) { AWorksheet.Cells[rowCounter, colCounter].Value = TVariant.DecodeFromString(value).ToDecimal(); } else { AWorksheet.Cells[rowCounter, colCounter].Value = value; } } colCounter++; } rowCounter++; colCounter = 1; } }
/// <summary> /// Executes the tests (main method of this executable!). /// </summary> public static void RunTest() { XmlNode startNode; XmlNode curGroup; Thread groupThread; TestGroup myGroup; String testcase; new TAppSettingsManager(true); testcase = TAppSettingsManager.GetValue("testcase"); Global.StartClientID = TAppSettingsManager.GetInt16("startclientid"); rnd = new System.Random(DateTime.Now.Millisecond); // Init try { parser = new TXMLParser(TAppSettingsManager.GetValue("testscript"), false); startNode = parser.GetDocument().DocumentElement; } catch (Exception E) { System.Console.WriteLine("{0}: trouble in RunTest", DateTime.Now.ToLongTimeString()); System.Console.WriteLine("{0}: {1}", DateTime.Now.ToLongTimeString(), E.Message); return; } new TLogging(@"..\..\log\PetraMultiStart.log"); // TheConnector = new Ict.Petra.ServerAdmin.App.Core.Connector.TConnector(); // TheConnector.GetServerConnection(TAppSettingsManager.ConfigFileName, out TRemote); TRemote = new TMServerAdminNamespace().WebConnectors; CreateTestUsers(); if (startNode.Name.ToLower() == "tests") { startNode = startNode.FirstChild; while ((startNode != null) && (startNode.Name.ToLower() == "test") && (TXMLParser.GetAttribute(startNode, "name") != testcase)) { startNode = startNode.NextSibling; } } if (startNode == null) { Console.WriteLine("{0}: cannot find testcase {1}", DateTime.Now.ToLongTimeString(), testcase); return; } while (true) { // restart the whole test scenario if (startNode.Name.ToLower() == "test") { Global.Filename = TXMLParser.GetAttribute(startNode, "app"); // kill instances of previous test KillAllProcesses(Global.Filename.Substring(0, Global.Filename.IndexOf('.'))); Global.Configfile = TXMLParser.GetAttribute(startNode, "config"); curGroup = startNode.FirstChild; while ((curGroup != null) && (curGroup.Name == "clientgroup")) { if (TXMLParser.GetBoolAttribute(curGroup, "active", true) != false) { myGroup = new TestGroup(curGroup); groupThread = new Thread(myGroup.Run); groupThread.Start(); } curGroup = curGroup.NextSibling; } } Thread.CurrentThread.Join(); System.Console.WriteLine("{0}: All threads have stopped", DateTime.Now.ToLongTimeString()); if (TXMLParser.GetBoolAttribute(startNode, "loop", true) == false) { return; } Thread.Sleep(5 * 60 * 1000); // wait for 5 minutes before restarting } }
/// <summary> /// constructor /// </summary> /// <param name="AReuseParser"></param> public TReportParser(TXMLParser AReuseParser) : base(AReuseParser) { }
/// <summary> /// store the data into Excel format, Open Office XML, .xlsx /// </summary> private static void Xml2ExcelWorksheet(XmlDocument ADoc, IWorkbook AWorkbook, ISheet AWorksheet, bool AWithHashInCaption = true) { Int32 rowCounter = 1; Int16 colCounter = 1; IRow wsrow = null; ICell wscell = null; ICellStyle wsstyle_dateformat = AWorkbook.CreateCellStyle(); ICreationHelper createHelper = AWorkbook.GetCreationHelper(); wsstyle_dateformat.DataFormat = createHelper.CreateDataFormat().GetFormat("dd/mm/yyyy"); // first write the header of the csv file List <string> AllAttributes = new List <string>(); List <XmlNode> AllNodes = new List <XmlNode>(); GetAllAttributesAndNodes(ADoc.DocumentElement, ref AllAttributes, ref AllNodes); wsrow = AWorksheet.CreateRow(rowCounter); foreach (string attrName in AllAttributes) { wscell = wsrow.CreateCell(colCounter); wscell.SetCellValue((AWithHashInCaption?"#":"") + attrName); colCounter++; } rowCounter++; colCounter = 1; foreach (XmlNode node in AllNodes) { wsrow = AWorksheet.CreateRow(rowCounter); foreach (string attrName in AllAttributes) { wscell = wsrow.CreateCell(colCounter); if (attrName == "childOf") { wscell.SetCellValue(TXMLParser.GetAttribute(node.ParentNode, "name")); } else { string value = TXMLParser.GetAttribute(node, attrName); if (value.StartsWith(eVariantTypes.eDateTime.ToString() + ":")) { wscell.SetCellValue(TVariant.DecodeFromString(value).ToDate()); wscell.CellStyle = wsstyle_dateformat; } else if (value.StartsWith(eVariantTypes.eInteger.ToString() + ":")) { wscell.SetCellValue(TVariant.DecodeFromString(value).ToInt64()); } else if (value.StartsWith(eVariantTypes.eDecimal.ToString() + ":")) { wscell.SetCellValue((double)TVariant.DecodeFromString(value).ToDecimal()); } else { wscell.SetCellValue(value); } } colCounter++; } rowCounter++; colCounter = 1; } }
/// <summary> /// Read the parameters from a text file (xml format); /// used for loading settings /// </summary> /// <param name="filename">relative or absolute filename /// </param> /// <returns>void</returns> public void Load(String filename) { XmlNode startNode; XmlNode node; TXMLParser myDoc; String level; String column; int levelNr; int columnNr; int subreport; myDoc = new TXMLParser(filename, false); try { startNode = myDoc.GetDocument().DocumentElement; if (startNode.Name.ToLower() == "parameters") { node = startNode.FirstChild; while (node != null) { if (node.Name == "Parameter") { column = TXMLParser.GetAttribute(node, "column"); level = TXMLParser.GetAttribute(node, "level"); subreport = TXMLParser.GetIntAttribute(node, "subreport"); columnNr = -1; levelNr = -1; if (column.Length != 0) { columnNr = (int)StringHelper.StrToInt(column); } if (level.Length != 0) { levelNr = (int)StringHelper.StrToInt(level); } Add(TXMLParser.GetAttribute(node, "id"), TVariant.DecodeFromString(TXMLParser.GetAttribute(node, "value")), columnNr, levelNr, subreport); } node = node.NextSibling; } } } catch (Exception E) { throw new Exception(E.Message); } }
/// <summary> /// Load an OpenDocument .ods file into a datatable /// </summary> public static DataTable ParseODSStream2DataTable(MemoryStream AStream, bool AHasHeader = false, int AWorksheetID = 0, List <string> AColumnsToImport = null) { XmlDocument doc = GetContent(AStream); XmlNode OfficeBody = TXMLParser.GetChild(doc.DocumentElement, "office:body"); XmlNode OfficeDocument = TXMLParser.GetChild(OfficeBody, "office:spreadsheet"); int countWorksheets = 0; XmlNode worksheet = null; foreach (XmlNode worksheetLoop in OfficeDocument.ChildNodes) { if (worksheetLoop.Name != "table:table") { continue; } if (countWorksheets == AWorksheetID) { worksheet = worksheetLoop; } countWorksheets++; } DataTable result = new DataTable(); if (worksheet == null) { return(result); } List <string> ColumnNames = new List <string>(); bool firstRow = true; foreach (XmlNode rowNode in worksheet.ChildNodes) { if (rowNode.Name != "table:table-row") { continue; } // create columns if (firstRow) { int columnCounter = 0; foreach (XmlNode cellNode in rowNode.ChildNodes) { if (cellNode.Name != "table:table-cell") { continue; } if (TXMLParser.HasAttribute(cellNode, "table:number-columns-repeated")) { // just ignore duplicate columns in the header line, the values must be unique anyway continue; } string ColumnName = ((AHasHeader && cellNode.FirstChild != null) ? cellNode.FirstChild.InnerText : string.Format("Column {0}", columnCounter)); ColumnNames.Add(ColumnName); columnCounter++; if ((AColumnsToImport != null) && !AColumnsToImport.Contains(ColumnName)) { continue; } result.Columns.Add(ColumnName); } } // import row if (!firstRow || !AHasHeader) { DataRow NewRow = result.NewRow(); int columnCounter = 0; foreach (XmlNode cellNode in rowNode.ChildNodes) { if (cellNode.Name != "table:table-cell") { continue; } Int32 NumberColumnsRepeated = 1; // handle columns with same value if (TXMLParser.HasAttribute(cellNode, "table:number-columns-repeated")) { NumberColumnsRepeated = Convert.ToInt32(TXMLParser.GetAttribute(cellNode, "table:number-columns-repeated")); if (!TXMLParser.HasAttribute(cellNode, "office:value-type")) { // skip empty columns columnCounter += NumberColumnsRepeated; continue; } } while (NumberColumnsRepeated > 0) { string CellType = TXMLParser.GetAttribute(cellNode, "office:value-type"); if ((AColumnsToImport != null) && !AColumnsToImport.Contains(ColumnNames[columnCounter])) { // skip this column } else if (CellType == "float") { TVariant variant = new TVariant(TXMLParser.GetAttribute(cellNode, "office:value")); NewRow[ColumnNames[columnCounter]] = variant.ToObject(); } else if (CellType == "date") { NewRow[ColumnNames[columnCounter]] = new TVariant(TXMLParser.GetAttribute(cellNode, "office:date-value")).EncodeToString(); } else if (CellType == "boolean") { NewRow[ColumnNames[columnCounter]] = (TXMLParser.GetAttribute(cellNode, "office:boolean-value") == "true"); } else if (CellType == "string") { NewRow[ColumnNames[columnCounter]] = cellNode.FirstChild.InnerText; } columnCounter++; NumberColumnsRepeated--; } } result.Rows.Add(NewRow); } firstRow = false; } return(result); }
/// <summary> /// Reads the binary data of the image and returns it as a formatted Base64 string /// which then can be used in a .resx file. /// It seems for bitmaps for buttons and toolbars and menuitems, we need gif bitmaps /// but for window icons we need ico files /// </summary> /// <param name="AImageFileName">Full file name of the image</param> /// <param name="AImageOrIcon">is this an icon or bitmap</param> /// <returns>the formatted Base64 representation of the image</returns> private string Image2Base64(string AImageFileName, string AImageOrIcon) { if (!File.Exists(AImageFileName)) { return ""; } // AlanP added this retry loop after getting fed up with generating the solution and finding that // access to go.gif.resx is denied. The assumption is that multi-threaded code generation // wants to access a well-used image file in multiple places. The resx file is only a temporary // file. A few lines down we delete it, which is probably why it fails to open. // If that is not the cause the code shouldn't do any harm. int nTries = 0; int nTriesLimit = 4; // 4 tries over 2 seconds should be enough! string exceptionMsg = String.Empty; TXMLParser parser = null; while (nTries < nTriesLimit) { try { System.Resources.ResXResourceWriter w = new System.Resources.ResXResourceWriter(AImageFileName + ".resx"); if (AImageOrIcon == "Icon") { w.AddResource(AImageFileName, new Icon(AImageFileName)); } else if ((AImageOrIcon == "Bitmap") && (Path.GetExtension(AImageFileName) == ".ico")) { w.AddResource(AImageFileName, (new Icon(AImageFileName)).ToBitmap()); } else { w.AddResource(AImageFileName, new Bitmap(AImageFileName)); } w.Close(); parser = new TXMLParser(AImageFileName + ".resx", false); File.Delete(AImageFileName + ".resx"); nTries = 999; // success! } catch (Exception ex) // probably an IO exception { nTries++; parser = null; exceptionMsg = ex.Message; Application.DoEvents(); System.Threading.Thread.Sleep(500); } } if ((nTries == nTriesLimit) || (parser == null)) { throw new IOException(String.Format( "The system had {0} attempts to create, parse and delete the file {1}.resx as a resource but the following IO exception was raised: {2}", nTries, AImageFileName, exceptionMsg)); } XmlDocument doc = parser.GetDocument(); XmlNode child = doc.DocumentElement.FirstChild; while (child != null) { if ((child.Name == "data") && (TYml2Xml.GetAttribute(child, "name") == AImageFileName)) { return child.InnerText; } child = child.NextSibling; } return string.Empty; }
/// <summary> /// code for generating typed datasets /// </summary> /// <param name="AInputXmlfile"></param> /// <param name="AOutputPath"></param> /// <param name="ANameSpace"></param> /// <param name="store"></param> /// <param name="groups"></param> /// <param name="AFilename"></param> public static void CreateTypedDataSets(String AInputXmlfile, String AOutputPath, String ANameSpace, TDataDefinitionStore store, string[] groups, string AFilename) { Console.WriteLine("processing dataset " + ANameSpace); string templateDir = TAppSettingsManager.GetValue("TemplateDir", true); ProcessTemplate Template = new ProcessTemplate(templateDir + Path.DirectorySeparatorChar + "ORM" + Path.DirectorySeparatorChar + "DataSet.cs"); Template.AddSnippetsFromOtherFile(templateDir + Path.DirectorySeparatorChar + "ORM" + Path.DirectorySeparatorChar + "DataTable.cs"); DataSetTableIdCounter = Convert.ToInt16(TAppSettingsManager.GetValue("StartTableId")); // load default header with license and copyright Template.SetCodelet("GPLFILEHEADER", ProcessTemplate.LoadEmptyFileComment(templateDir)); Template.SetCodelet("NAMESPACE", ANameSpace); // if no dataset is defined yet in the xml file, the following variables can be empty Template.AddToCodelet("USINGNAMESPACES", ""); Template.AddToCodelet("CONTENTDATASETSANDTABLESANDROWS", ""); TXMLParser parserDataSet = new TXMLParser(AInputXmlfile, false); XmlDocument myDoc = parserDataSet.GetDocument(); XmlNode startNode = myDoc.DocumentElement; if (startNode.Name.ToLower() == "petradatasets") { XmlNode cur = TXMLParser.NextNotBlank(startNode.FirstChild); while ((cur != null) && (cur.Name.ToLower() == "importunit")) { Template.AddToCodelet("USINGNAMESPACES", "using " + TXMLParser.GetAttribute(cur, "name") + ";" + Environment.NewLine); cur = TXMLParser.GetNextEntity(cur); } while ((cur != null) && (cur.Name.ToLower() == "dataset")) { ProcessTemplate snippetDataset = Template.GetSnippet("TYPEDDATASET"); string datasetname = TXMLParser.GetAttribute(cur, "name"); snippetDataset.SetCodelet("DATASETNAME", datasetname); // INITCONSTRAINTS and INITRELATIONS can be empty snippetDataset.AddToCodelet("INITCONSTRAINTS", ""); snippetDataset.AddToCodelet("INITRELATIONS", ""); SortedList <string, TDataSetTable>tables = new SortedList <string, TDataSetTable>(); XmlNode curChild = cur.FirstChild; while (curChild != null) { if ((curChild.Name.ToLower() == "table") && TXMLParser.HasAttribute(curChild, "sqltable")) { bool OverloadTable = false; string tabletype = TTable.NiceTableName(TXMLParser.GetAttribute(curChild, "sqltable")); string variablename = (TXMLParser.HasAttribute(curChild, "name") ? TXMLParser.GetAttribute(curChild, "name") : tabletype); TDataSetTable table = new TDataSetTable( TXMLParser.GetAttribute(curChild, "sqltable"), tabletype, variablename, store.GetTable(tabletype)); XmlNode tableNodes = curChild.FirstChild; while (tableNodes != null) { if (tableNodes.Name.ToLower() == "customfield") { // eg. BestAddress in PartnerEditTDS.PPartnerLocation TTableField customField = new TTableField(); customField.strName = TXMLParser.GetAttribute(tableNodes, "name"); customField.strTypeDotNet = TXMLParser.GetAttribute(tableNodes, "type"); customField.strDescription = TXMLParser.GetAttribute(tableNodes, "comment"); customField.strDefault = TXMLParser.GetAttribute(tableNodes, "initial"); table.grpTableField.Add(customField); OverloadTable = true; } if (tableNodes.Name.ToLower() == "field") { // eg. UnitName in PartnerEditTDS.PPerson TTableField field = new TTableField(store.GetTable(TXMLParser.GetAttribute(tableNodes, "sqltable")). GetField(TXMLParser.GetAttribute(tableNodes, "sqlfield"))); if (TXMLParser.HasAttribute(tableNodes, "name")) { field.strNameDotNet = TXMLParser.GetAttribute(tableNodes, "name"); } if (TXMLParser.HasAttribute(tableNodes, "comment")) { field.strDescription = TXMLParser.GetAttribute(tableNodes, "comment"); } table.grpTableField.Add(field); OverloadTable = true; } if (tableNodes.Name.ToLower() == "primarykey") { TConstraint primKeyConstraint = table.GetPrimaryKey(); primKeyConstraint.strThisFields = StringHelper.StrSplit(TXMLParser.GetAttribute(tableNodes, "thisFields"), ","); OverloadTable = true; } tableNodes = tableNodes.NextSibling; } if (OverloadTable) { tabletype = datasetname + TTable.NiceTableName(table.strName); if (TXMLParser.HasAttribute(curChild, "name")) { tabletype = datasetname + TXMLParser.GetAttribute(curChild, "name"); } table.strDotNetName = tabletype; table.strVariableNameInDataset = variablename; // set tableid table.iOrder = DataSetTableIdCounter++; // TODO: can we derive from the base table, and just overload a few functions? CodeGenerationTable.InsertTableDefinition(snippetDataset, table, store.GetTable(table.tableorig), "TABLELOOP"); CodeGenerationTable.InsertRowDefinition(snippetDataset, table, store.GetTable(table.tableorig), "TABLELOOP"); } tables.Add(variablename, table); AddTableToDataset(tabletype, variablename, snippetDataset); } else if ((curChild.Name.ToLower() == "table") && TXMLParser.HasAttribute(curChild, "customtable")) { // this refers to a custom table of another dataset, eg. BestAddressTDSLocation // for the moment, such a table cannot have additional fields if (curChild.HasChildNodes) { throw new Exception( String.Format( "CreateTypedDataSets(): At the moment, a custom table referenced from another dataset cannot have additional fields. Dataset: {0}, Table: {1}", datasetname, TXMLParser.HasAttribute(curChild, "customtable"))); } // customtable has to contain the name of the dataset, eg. BestAddressTDSLocation string tabletype = TXMLParser.GetAttribute(curChild, "customtable"); string variablename = (TXMLParser.HasAttribute(curChild, "name") ? TXMLParser.GetAttribute(curChild, "name") : tabletype); AddTableToDataset(tabletype, variablename, snippetDataset); } if (curChild.Name.ToLower() == "customrelation") { ProcessTemplate tempSnippet = Template.GetSnippet("INITRELATIONS"); tempSnippet.SetCodelet("RELATIONNAME", TXMLParser.GetAttribute(curChild, "name")); tempSnippet.SetCodelet("TABLEVARIABLENAMEPARENT", TXMLParser.GetAttribute(curChild, "parentTable")); tempSnippet.SetCodelet("TABLEVARIABLENAMECHILD", TXMLParser.GetAttribute(curChild, "childTable")); tempSnippet.SetCodelet("COLUMNNAMESPARENT", StringCollectionToValuesFormattedForArray(tables, TXMLParser.GetAttribute(curChild, "parentTable"), StringHelper.StrSplit(TXMLParser.GetAttribute(curChild, "parentFields"), ","))); tempSnippet.SetCodelet("COLUMNNAMESCHILD", StringCollectionToValuesFormattedForArray(tables, TXMLParser.GetAttribute(curChild, "childTable"), StringHelper.StrSplit(TXMLParser.GetAttribute(curChild, "childFields"), ","))); tempSnippet.SetCodelet("CREATECONSTRAINTS", TXMLParser.GetBoolAttribute(curChild, "createConstraints") ? "true" : "false"); snippetDataset.InsertSnippet("INITRELATIONS", tempSnippet); } if (curChild.Name.ToLower() == "customtable") { string variablename = TXMLParser.GetAttribute(curChild, "name"); string tabletype = datasetname + TXMLParser.GetAttribute(curChild, "name"); XmlNode customTableNodes = curChild.FirstChild; TDataSetTable customTable = new TDataSetTable( tabletype, tabletype, variablename, null); // set TableId customTable.iOrder = DataSetTableIdCounter++; customTable.strDescription = TXMLParser.GetAttribute(curChild, "comment"); customTable.strName = tabletype; customTable.strDotNetName = tabletype; customTable.strVariableNameInDataset = variablename; while (customTableNodes != null) { if (customTableNodes.Name.ToLower() == "customfield") { TTableField customField = new TTableField(); customField.strName = TXMLParser.GetAttribute(customTableNodes, "name"); customField.strTypeDotNet = TXMLParser.GetAttribute(customTableNodes, "type"); customField.strDescription = TXMLParser.GetAttribute(customTableNodes, "comment"); customField.strDefault = TXMLParser.GetAttribute(customTableNodes, "initial"); customTable.grpTableField.Add(customField); } if (customTableNodes.Name.ToLower() == "field") { // eg. SelectedSiteKey in PartnerEditTDS.MiscellaneousData TTableField field = new TTableField(store.GetTable(TXMLParser.GetAttribute(customTableNodes, "sqltable")). GetField(TXMLParser.GetAttribute(customTableNodes, "sqlfield"))); if (TXMLParser.HasAttribute(customTableNodes, "name")) { field.strNameDotNet = TXMLParser.GetAttribute(customTableNodes, "name"); } if (TXMLParser.HasAttribute(customTableNodes, "comment")) { field.strDescription = TXMLParser.GetAttribute(customTableNodes, "comment"); } customTable.grpTableField.Add(field); } if (customTableNodes.Name.ToLower() == "primarykey") { TConstraint primKeyConstraint = new TConstraint(); primKeyConstraint.strName = "PK"; primKeyConstraint.strType = "primarykey"; primKeyConstraint.strThisFields = StringHelper.StrSplit(TXMLParser.GetAttribute(customTableNodes, "thisFields"), ","); customTable.grpConstraint.Add(primKeyConstraint); } customTableNodes = customTableNodes.NextSibling; } tables.Add(tabletype, customTable); AddTableToDataset(tabletype, variablename, snippetDataset); CodeGenerationTable.InsertTableDefinition(snippetDataset, customTable, null, "TABLELOOP"); CodeGenerationTable.InsertRowDefinition(snippetDataset, customTable, null, "TABLELOOP"); } curChild = curChild.NextSibling; } foreach (TDataSetTable table in tables.Values) { // todo? also other constraints, not only from original table? foreach (TConstraint constraint in table.grpConstraint) { if ((constraint.strType == "foreignkey") && tables.ContainsKey(constraint.strOtherTable)) { TDataSetTable otherTable = (TDataSetTable)tables[constraint.strOtherTable]; ProcessTemplate tempSnippet = Template.GetSnippet("INITCONSTRAINTS"); tempSnippet.SetCodelet("TABLEVARIABLENAME1", table.tablealias); tempSnippet.SetCodelet("TABLEVARIABLENAME2", otherTable.tablealias); tempSnippet.SetCodelet("CONSTRAINTNAME", TTable.NiceKeyName(constraint)); tempSnippet.SetCodelet("COLUMNNAMES1", StringCollectionToValuesFormattedForArray(constraint.strThisFields)); tempSnippet.SetCodelet("COLUMNNAMES2", StringCollectionToValuesFormattedForArray(constraint.strOtherFields)); snippetDataset.InsertSnippet("INITCONSTRAINTS", tempSnippet); } } } Template.InsertSnippet("CONTENTDATASETSANDTABLESANDROWS", snippetDataset); cur = TXMLParser.GetNextEntity(cur); } } Template.FinishWriting(AOutputPath + Path.DirectorySeparatorChar + AFilename + "-generated.cs", ".cs", true); }
/// <summary> /// main function for generating access methods for typed data sets /// </summary> /// <param name="AInputXmlfile"></param> /// <param name="AOutputPath"></param> /// <param name="ANameSpace"></param> /// <param name="store"></param> /// <param name="groups"></param> /// <param name="AFilename"></param> public static void CreateTypedDataSets(String AInputXmlfile, String AOutputPath, String ANameSpace, TDataDefinitionStore store, string[] groups, string AFilename) { Console.WriteLine("processing dataset " + ANameSpace); string templateDir = TAppSettingsManager.GetValue("TemplateDir", true); ProcessTemplate Template = new ProcessTemplate(templateDir + Path.DirectorySeparatorChar + "ORM" + Path.DirectorySeparatorChar + "DataSetAccess.cs"); // load default header with license and copyright Template.SetCodelet("GPLFILEHEADER", ProcessTemplate.LoadEmptyFileComment(templateDir)); Template.SetCodelet("NAMESPACE", ANameSpace); // if no dataset is defined yet in the xml file, the following variables can be empty Template.AddToCodelet("USINGNAMESPACES", ""); Template.AddToCodelet("CONTENTDATASETSANDTABLESANDROWS", ""); Template.AddToCodelet("USINGNAMESPACES", "using " + ANameSpace.Replace(".Server.", ".Shared.") + ";" + Environment.NewLine, false); TXMLParser parserDataSet = new TXMLParser(AInputXmlfile, false); XmlDocument myDoc = parserDataSet.GetDocument(); XmlNode startNode = myDoc.DocumentElement; if (startNode.Name.ToLower() == "petradatasets") { XmlNode cur = TXMLParser.NextNotBlank(startNode.FirstChild); while ((cur != null) && (cur.Name.ToLower() == "importunit")) { Template.AddToCodelet("USINGNAMESPACES", "using " + TXMLParser.GetAttribute(cur, "name") + ";" + Environment.NewLine, false); Template.AddToCodelet("USINGNAMESPACES", "using " + TXMLParser.GetAttribute(cur, "name").Replace(".Shared.", ".Server.") + ".Access;" + Environment.NewLine, false); cur = TXMLParser.GetNextEntity(cur); } while ((cur != null) && (cur.Name.ToLower() == "dataset")) { ProcessTemplate snippetDataset = Template.GetSnippet("TYPEDDATASET"); string datasetname = TXMLParser.GetAttribute(cur, "name"); snippetDataset.SetCodelet("DATASETNAME", datasetname); ProcessTemplate snippetSubmitChanges = snippetDataset.GetSnippet("SUBMITCHANGESFUNCTION"); snippetSubmitChanges.AddToCodelet("DATASETNAME", datasetname); List <TDataSetTable>tables = new List <TDataSetTable>(); XmlNode curChild = cur.FirstChild; // first collect the tables while (curChild != null) { if (curChild.Name.ToLower() == "table") { string tabletype = TTable.NiceTableName(TXMLParser.GetAttribute(curChild, "sqltable")); string variablename = (TXMLParser.HasAttribute(curChild, "name") ? TXMLParser.GetAttribute(curChild, "name") : tabletype); TDataSetTable table = new TDataSetTable( TXMLParser.GetAttribute(curChild, "sqltable"), tabletype, variablename, store.GetTable(tabletype)); tables.Add(table); } curChild = curChild.NextSibling; } foreach (TDataSetTable table in tables) { AddTableToDataset(tables, store.GetTable(table.tableorig), table.tablename, table.tablealias, snippetDataset, snippetSubmitChanges); } // there is one codelet for the dataset name. // only add the full submitchanges function if there are any table to submit if (snippetSubmitChanges.FCodelets.Count > 1) { snippetDataset.InsertSnippet("SUBMITCHANGESFUNCTION", snippetSubmitChanges); } else { snippetDataset.AddToCodelet("SUBMITCHANGESFUNCTION", ""); } Template.InsertSnippet("CONTENTDATASETSANDTABLESANDROWS", snippetDataset); cur = TXMLParser.GetNextEntity(cur); } } Template.FinishWriting(AOutputPath + Path.DirectorySeparatorChar + AFilename + "-generated.cs", ".cs", true); }
/// <summary> /// load the dataset tables /// </summary> public static SortedList <string, TTable>LoadDatasetTables(string AICTPath, string ADataSetTypeWithNamespace, TCodeStorage ACodeStorage, string APluginPath) { if (FDatasetTables == null) { FDatasetTables = new SortedList <string, SortedList <string, TTable>>(); } FCodeStorage = ACodeStorage; if (!ADataSetTypeWithNamespace.StartsWith("Ict.Petra.Shared") && !ADataSetTypeWithNamespace.StartsWith("Ict.Petra.Plugins")) { throw new Exception("the DatasetType must contain the full namespace, starting with Ict.Petra.Shared or Ict.Petra.Plugins"); } if (FDatasetTables.ContainsKey(ADataSetTypeWithNamespace)) { FCurrentDataset = FDatasetTables[ADataSetTypeWithNamespace]; return FCurrentDataset; } string[] datasetTypeSplit = ADataSetTypeWithNamespace.Split(new char[] { '.' }); string module = datasetTypeSplit[3]; string datasetName = datasetTypeSplit[datasetTypeSplit.Length - 1]; // find the correct xml file for the dataset. // look in Ict/Petra/Shared/lib/MODULE/data string dataPath = AICTPath + "/Petra/Shared/lib/" + module + "/data/"; if (ADataSetTypeWithNamespace.StartsWith("Ict.Petra.Plugins")) { int start = "Ict.Petra.Plugins.".Length; int end = ADataSetTypeWithNamespace.IndexOf(".", start); string PluginName = ADataSetTypeWithNamespace.Substring(start, end - start); dataPath = AICTPath + "/Petra/Plugins/" + PluginName + "/data/"; } DirectoryInfo directory = new DirectoryInfo(dataPath); FileInfo[] xmlFiles = directory.GetFiles("*.xml"); XmlNode datasetNode = null; foreach (FileInfo fileinfo in xmlFiles) { if (datasetNode == null) { TXMLParser parser = new TXMLParser(dataPath + "/" + fileinfo.Name, false); datasetNode = parser.GetDocument().SelectSingleNode(String.Format("//DataSet[@name='{0}']", datasetName)); } } if ((datasetNode == null) && File.Exists(APluginPath)) { // also check the plugin directory of the yaml file, for plugins can have a file TypedDataSets.xml TXMLParser parser = new TXMLParser(APluginPath, false); datasetNode = parser.GetDocument().SelectSingleNode(String.Format("//DataSet[@name='{0}']", datasetName)); } if (datasetNode == null) { throw new Exception("cannot find the xml file for dataset " + ADataSetTypeWithNamespace); } SortedList <string, TTable>result = new SortedList <string, TTable>(); XmlNodeList tables = datasetNode.SelectNodes("Table|CustomTable"); foreach (XmlNode tableNode in tables) { TTable table = new TTable(); string tablename; if ((tableNode.Name == "Table") && TXMLParser.HasAttribute(tableNode, "sqltable")) { tablename = TTable.NiceTableName(tableNode.Attributes["sqltable"].Value); table.Assign(FPetraXMLStore.GetTable(tablename)); table.strVariableNameInDataset = TXMLParser.HasAttribute(tableNode, "name") ? tableNode.Attributes["name"].Value : tablename; if ((tableNode.SelectNodes("CustomField").Count > 0) || (tableNode.SelectNodes("Field").Count > 0)) { table.strDotNetName = datasetName + tablename; } } else if ((tableNode.Name == "Table") && TXMLParser.HasAttribute(tableNode, "customtable")) { table = new TTable(); tablename = tableNode.Attributes["customtable"].Value; table.strName = tablename; table.strDotNetName = tablename; table.strVariableNameInDataset = TXMLParser.HasAttribute(tableNode, "name") ? tableNode.Attributes["name"].Value : tablename; } else { table = new TTable(); tablename = tableNode.Attributes["name"].Value; table.strName = tablename; table.strDotNetName = datasetName + tablename; table.strVariableNameInDataset = tablename; } // add the custom fields if there are any XmlNodeList customFields = tableNode.SelectNodes("CustomField"); foreach (XmlNode customField in customFields) { TTableField newField = new TTableField(); newField.strName = customField.Attributes["name"].Value; newField.strNameDotNet = newField.strName; newField.strType = customField.Attributes["type"].Value; newField.strTypeDotNet = customField.Attributes["type"].Value; newField.strTableName = tablename; newField.strDescription = ""; newField.bNotNull = TXMLParser.HasAttribute(customField, "notnull") && TXMLParser.GetAttribute(customField, "notnull").ToLower() == "true"; table.grpTableField.Add(newField); } // add other fields from other tables that are defined in petra.xml XmlNodeList otherFields = tableNode.SelectNodes("Field"); foreach (XmlNode otherField in otherFields) { TTable otherTable = FPetraXMLStore.GetTable(otherField.Attributes["sqltable"].Value); TTableField newField = new TTableField(otherTable.GetField(otherField.Attributes["sqlfield"].Value)); if (TXMLParser.HasAttribute(otherField, "name")) { newField.strNameDotNet = otherField.Attributes["name"].Value; } newField.strTableName = tablename; table.grpTableField.Add(newField); } result.Add(table.strVariableNameInDataset, table); } FDatasetTables.Add(ADataSetTypeWithNamespace, result); FCurrentDataset = result; return result; }
/// <summary> /// copy constructor /// </summary> /// <param name="AReuseParser"></param> public TXMLParser(TXMLParser AReuseParser) : base() { this.myDoc = AReuseParser.myDoc; }