/// <summary> /// Start of the Depth First Directed Acyclic Forest Traversal Algorithm to identify and extract the dependencies from within their references in the schema XSD /// </summary> /// <param name="schemaAtKey"></param> /// <param name="newGraphDict"></param> /// <param name="dllName"></param> /// <param name="outputDir"></param> public void FileReadDFS(SchemaDetails schemaAtKey, ref Dictionary <SchemaDetails, List <SchemaDetails> > newGraphDict, string dllName, string outputDir) { try { if (visited[schemaAtKey] == false) { visited[schemaAtKey] = true; var dependencyList = UpdateSchemaContent(dllName, schemaAtKey, outputDir); newGraphDict[schemaAtKey] = dependencyList; if (dependencyList.Count == 0) { return; } foreach (var dep in dependencyList) { FileReadDFS(dep, ref newGraphDict, dllName, outputDir); } } } catch (Exception e) { string message = $"ERROR! Problem during extraction of schema dependency from DLLs. Schema:{schemaAtKey.fullNameOfSchemaToUpload} \nErrorMessage:{e.Message}"; TraceProvider.WriteLine($"{message} \nStackTrace:{e.StackTrace}"); //Console.WriteLine($"{message} \nStackTrace:{e.StackTrace}"); schemaAtKey.errorDetailsForExtraction = schemaAtKey.errorDetailsForExtraction + "\n" + message; } }
internal void DFS(SchemaDetails schema) { if (visited[schema] == false) { visited[schema] = true; foreach (var i in adjacencyList[schema]) { DFS(i); } this.dependencyList.Add(schema); } }
/// <summary> /// Once you encounter a dependent schema name in the content of the current schema, replace the name of the schema as per the convention we have documented. /// </summary> /// <param name="dllName"></param> /// <param name="thisSchemaObj"></param> /// <param name="outputDir"></param> /// <returns>Returns the dependent schema list</returns> private List <SchemaDetails> UpdateSchemaContent(string dllName, SchemaDetails thisSchemaObj, string outputDir) { var dependentSchemaList = new List <SchemaDetails>(); var schemaXmlDoc = new XmlDocument(); // PUT IT IN TRY var schemaXmlContext = File.ReadAllText(outputDir + "\\AllSchemas\\" + thisSchemaObj.fullNameOfSchemaToUpload + ".xsd"); // Read dependencies schemaXmlDoc.LoadXml(schemaXmlContext); var schemaNodeChildren = schemaXmlDoc.DocumentElement; var x = schemaNodeChildren.ChildNodes; // loop thru the child nodes of the XSD schema to look for "import" or imports" nodes to extract names of dependent schemas from them foreach (XmlNode child in schemaNodeChildren) { try { // looks for dependent schema in "imports" XML tag if (child.Name.Contains("annotation") && child.ChildNodes.Count > 0) { foreach (XmlNode node in child) { if (node.Name.ToLower().Contains("appinfo") && node.ChildNodes.Count > 0) { foreach (XmlNode subnode in node) { if (subnode.Name.ToLower().Contains("imports") && subnode.ChildNodes.Count > 0) { foreach (XmlNode importNode in subnode) { if (importNode.Name.ToLower().Contains("namespace") && importNode.ChildNodes.Count == 0) { var location = importNode.Attributes["location"].Value; var dependentSchemaOriginalName = location.Substring(location.LastIndexOf(".")).Remove(0, 1); var dependentSchemaObj = this.originalSchemDetailsList.First(r => r.schemaFullName == location); var dependentSchemaNewName = dependentSchemaObj.fullNameOfSchemaToUpload; if (dependentSchemaNewName.Length > 79) { dependentSchemaNewName = dependentSchemaNewName.Replace("_", ""); } importNode.Attributes["location"].Value = location.Replace(importNode.Attributes["location"].Value, ".\\" + dependentSchemaNewName + ".xsd"); schemaXmlContext = schemaXmlContext.Replace("location=\"" + location + "\"", "location=\"" + importNode.Attributes["location"].Value + "\""); dependentSchemaList.Add(originalSchemDetailsList.First(r => r.fullNameOfSchemaToUpload == dependentSchemaNewName)); thisSchemaObj.dependentSchemas.Add(dependentSchemaNewName); if (dependentSchemaObj.isSchemaExtractedFromDb == false) { visited[dependentSchemaObj] = false; TraceProvider.WriteLine($"Extracted an unselected dependency schema: {dependentSchemaObj.fullNameOfSchemaToUpload}"); Console.WriteLine($"Extracted an unselected dependency schema: {dependentSchemaObj.fullNameOfSchemaToUpload}"); } } } } } } } } // look for dependent schema in "import" XML tag if (child.Name.ToLower().Contains("import") && child.ChildNodes.Count == 0) { var schemaLocation = child.Attributes["schemaLocation"].Value; var dependentSchemaOriginalName = schemaLocation.Substring(schemaLocation.LastIndexOf(".")).Remove(0, 1); var dependentSchemaObj = this.originalSchemDetailsList.First(r => r.schemaFullName == schemaLocation); var m = schemaNodeChildren.GetElementsByTagName("import"); var dependentSchemaNewName = dependentSchemaObj.fullNameOfSchemaToUpload; //var dependentSchemaNewName = dllName + "_" + dependentSchemaOriginalName; if (dependentSchemaNewName.Length > 79) { dependentSchemaNewName = dependentSchemaNewName.Replace("_", ""); } child.Attributes["schemaLocation"].Value = schemaLocation.Replace(child.Attributes["schemaLocation"].Value, ".\\" + dependentSchemaNewName + ".xsd"); schemaXmlContext = schemaXmlContext.Replace("schemaLocation=\"" + schemaLocation + "\"", "schemaLocation=\"" + child.Attributes["schemaLocation"].Value + "\""); dependentSchemaList.Add(originalSchemDetailsList.First(r => r.fullNameOfSchemaToUpload == dependentSchemaNewName)); thisSchemaObj.dependentSchemas.Add(dependentSchemaNewName); if (dependentSchemaObj.isSchemaExtractedFromDb == false) { visited[dependentSchemaObj] = false; TraceProvider.WriteLine($"Extracted an unselected dependency schema: {dependentSchemaObj.fullNameOfSchemaToUpload}"); // Console.WriteLine($"Extracted an unselected dependency schema: {dependentSchemaObj.fullNameOfSchemaToUpload}"); } } } catch (Exception e) { string message = $"ERROR! Problem extracting dependencies from schema {thisSchemaObj.fullNameOfSchemaToUpload}. \nErrorMessage:{e.Message}"; TraceProvider.WriteLine(message + " \nStackTrace:{e.StackTrace}"); //Console.WriteLine(message + " \nStackTrace:{e.StackTrace}"); thisSchemaObj.errorDetailsForExtraction = thisSchemaObj.errorDetailsForExtraction + "\n" + message; } } var schemaFilePath = string.Format(outputDir + "\\{0}.xsd", thisSchemaObj.fullNameOfSchemaToUpload); File.WriteAllText(schemaFilePath, schemaXmlContext, Encoding.UTF8); return(dependentSchemaList); }
/// <summary> /// Function to get the list of schemas /// </summary> /// <param name="sqlConnectionString"></param> /// <param name="outputDir"></param> /// <returns></returns> public List <SchemaDetails> GetListOfSchemas(string sqlConnectionString, string outputDir) { SetSchemAndDllDirectories(outputDir); var schemaDetailsObj = new SchemaDetails(); var originalSchemaDetailsObj = new SchemaDetails(); using (SqlConnection cn = new SqlConnection(sqlConnectionString)) { var query = ConfigurationManager.AppSettings["SchemaQuery"]; //or nvcFullName like 'MSIT.EAS.ICOE.VL.PosOrdrsp.Shared.Schemas.AP%' //or nvcFullName like 'MSIT.EAS.ICOE.VL.ZInvoic.Shared.Schemas.AP%' //or nvcFullName like 'MSIT.EAS.ICOE.VL.PropertySchemas%') //and nvcFullName like 'MSIT.EAS.ICOE.VL.Ordrsp.Shared.Schemas.AP%'"; using (var cmd = new SqlCommand(query, cn)) { if (cn.State == System.Data.ConnectionState.Closed) { try { cn.Open(); } catch (Exception e) { string message = $"ERROR! Unable to establish connection to the database. \nErrorMessage:{e.Message}"; TraceProvider.WriteLine($"{message} \nStackTrace:{e.StackTrace}"); //Console.WriteLine($"{message} \nStackTrace:{e.StackTrace}"); throw new Exception(message); } } using (var rdr = cmd.ExecuteReader()) { while (rdr.Read()) { schemaDetailsObj = new SchemaDetails(); originalSchemaDetailsObj = new SchemaDetails(); schemaDetailsObj.assemblyFullyQualifiedName = rdr["nvcFullName"].ToString(); originalSchemaDetailsObj.assemblyFullyQualifiedName = rdr["nvcFullName"].ToString(); schemaDetailsObj.schemaUploadToIAStatus = SchemaUploadToIAStatus.NotYetStarted; schemaDetailsObj.errorDetailsForMigration = ""; schemaDetailsObj.errorDetailsForExtraction = ""; schemaDetailsObj.dependentSchemas = new List <string>(); schemaDetailsObj.schemaFilesLocation = outputDir; schemaDetailsObj.schemaFullName = rdr["FullName"].ToString(); originalSchemaDetailsObj.schemaFullName = rdr["FullName"].ToString(); schemaDetailsObj.schemaName = rdr["Name"].ToString(); originalSchemaDetailsObj.schemaName = rdr["Name"].ToString(); schemaDetailsObj.schemaNamespace = rdr["Namespace"].ToString(); schemaDetailsObj.version = rdr["nvcVersion"].ToString(); schemaDetailsList.Add(schemaDetailsObj); originalSchemDetailsList.Add(originalSchemaDetailsObj); } } } } Directory.CreateDirectory(schemaOutputDir); Directory.CreateDirectory(schemaOutputDir + "\\AllSchemas"); PutAllSchemasToLocalFolder(ref schemaDetailsList, outputDir); return(schemaDetailsList); }
/// <summary> /// Putting all schemas to a local folder /// </summary> /// <param name="schemaDetailsList"></param> /// <param name="outputDir"></param> public void PutAllSchemasToLocalFolder(ref List <SchemaDetails> schemaDetailsList, string outputDir) { var distinctAssembliesList = new HashSet <string>(); foreach (var schemaObj in schemaDetailsList) { distinctAssembliesList.Add(schemaObj.assemblyFullyQualifiedName); } try { foreach (var fqnForAssembly in distinctAssembliesList) { var dllName = Path.GetFileName(fqnForAssembly).Replace(".dll", string.Empty).Replace('.', '_').Substring(0, Path.GetFileName(fqnForAssembly).IndexOf(',')); dllName = dllName + "_V" + fqnForAssembly.Substring(fqnForAssembly.IndexOf("Version"), 15).Replace(".", "_").Replace("Version=", ""); //Load the assembly into memory Assembly asm; try { asm = Assembly.Load(fqnForAssembly); } catch (FileNotFoundException e) { TraceProvider.WriteLine($"WARNING! Assembly with name {fqnForAssembly} to which identified Schemas belong is not found in GAC'ed DLLs. Message:{e.Message}"); //Console.WriteLine($"WARNING! Assembly with name {fqnForAssembly} to which identified Schemas belong is not found in GAC'ed DLLs. Message:{e.Message}"); continue; } var schemaObj = new SchemaDetails(); var originalSchemaObj = new SchemaDetails(); foreach (Type ty in asm.GetTypes()) { try { schemaObj = schemaDetailsList.First <SchemaDetails>(r => r.schemaName == ty.Name && r.assemblyFullyQualifiedName == ty.Assembly.FullName); originalSchemaObj = originalSchemDetailsList.First <SchemaDetails>(r => r.schemaName == ty.Name && r.assemblyFullyQualifiedName == ty.Assembly.FullName); } catch (Exception e) { continue; } try { // for every new schema in the DLL if (ty.BaseType != null && ty.BaseType.FullName == "Microsoft.XLANGs.BaseTypes.SchemaBase") { var sb = System.Activator.CreateInstance(ty) as SchemaBase; var schemaFileName = ty.Name; if (ty.DeclaringType == null) { var schemaXmlContext = sb.XmlContent; schemaXmlContext = schemaXmlContext.Replace("utf-16", "utf-8"); Match matchVersion = Regex.Match(schemaXmlContext, "standards_version=\"(.*?)\""); Match matchNamespace = Regex.Match(schemaXmlContext, "targetNamespace=\"(.*?)\""); if (matchVersion.Success && matchNamespace.Success) { if (!schemaNamespaceVersionDict.ContainsKey(matchNamespace.Groups[1].Value)) { schemaNamespaceVersionDict.Add(matchNamespace.Groups[1].Value, matchVersion.Groups[1].Value); } } schemaFileName = dllName + "_" + schemaFileName; // truncate the length of the schema if its more than what the IA can handle if (schemaFileName.Length > 79) { schemaFileName = schemaFileName.Replace("_", ""); } schemaObj.fullNameOfSchemaToUpload = schemaFileName; originalSchemaObj.fullNameOfSchemaToUpload = schemaFileName; // Write to file var schemaFilePath = string.Format(outputDir + "\\AllSchemas\\{0}.xsd", schemaFileName); File.WriteAllText(schemaFilePath, schemaXmlContext, Encoding.UTF8); } } } catch (Exception e) { string message = $"ERROR! Problem reading schema content from SchemaBase and Writing the file to Local Folder. \nSchema:{schemaObj.schemaFullName} \nAssembly:{schemaObj.assemblyFullyQualifiedName} \nErrorMessage: {e.Message}"; TraceProvider.WriteLine($"{message} \nStackTrace:{e.StackTrace}"); //Console.WriteLine($"{message} \nStackTrace:{e.StackTrace}"); throw new Exception(message); } } } } catch (Exception e) { string message = $"ERROR! Something went wrong. \nErrorMessage:{e.Message}"; TraceProvider.WriteLine($"{message} \nStackTrace:{e.StackTrace}"); //Console.WriteLine($"{message} \nStackTrace:{e.StackTrace}"); throw new Exception(message); } }