private static List <string> EqualWSDLDirectories(string pathSource, string pathNew, IOutputService output) { string fileWildcard = @"*.*"; var searchSubDirsArg = System.IO.SearchOption.AllDirectories; string[] FilesDirectorySource = System.IO.Directory.GetFiles(pathSource, fileWildcard, searchSubDirsArg); List <string> Diffs = new List <string>(); foreach (string fileSourcePath in FilesDirectorySource) { string fileNewPath = Path.Combine(pathNew, Path.GetFileName(fileSourcePath)); if (File.Exists(fileNewPath)) { FileInfo fileNew = new FileInfo(fileNewPath); FileInfo fileSource = new FileInfo(fileSourcePath); if (!Utility.FilesAreEqual(fileSource, fileNew)) { Diffs.Add(fileSourcePath); } } else { KBDoctorOutput.Message("-- No existe: " + fileNewPath); } } return(Diffs); }
// public static void CheckVariableUsages(KnowledgeBase KB, List<KBObject> objs, ref string recommendations, out int cant) { int cant_aux; cant = 0; KBDoctorOutput.StartSection("KBDoctor - Check variable usages"); foreach(KBObject obj in objs) { KBDoctorOutput.Message("Checking object: " + obj.QualifiedName); Objects.CheckVariableUsages(KB.DesignModel, obj, ref recommendations, out cant_aux); cant += cant_aux; } KBDoctorOutput.EndSection("KBDoctor - Check variable usages"); }
private static List <string> EqualNavigationDirectories(string pathSource, string pathNew, IOutputService output) { string fileWildcard = @"*.*"; var searchSubDirsArg = System.IO.SearchOption.AllDirectories; string[] FilesDirectorySource = System.IO.Directory.GetFiles(pathSource, fileWildcard, searchSubDirsArg); List <string> Diffs = new List <string>(); foreach (string fileSourcePath in FilesDirectorySource) { string fileNewPath = Path.Combine(pathNew, Path.GetFileName(fileSourcePath)); if (File.Exists(fileNewPath)) { FileInfo fileNew = new FileInfo(fileNewPath); FileInfo fileSource = new FileInfo(fileSourcePath); if (!Utility.FilesAreEqual(fileSource, fileNew)) { StreamReader sr = new StreamReader(fileNewPath); string datalineNew = sr.ReadLine(); string namelineNew = sr.ReadLine(); Encoding encnew = sr.CurrentEncoding; sr.Close(); DeleteFirstLines(2, fileNewPath); string textnew = File.ReadAllText(fileNewPath); sr = new StreamReader(fileSourcePath); string datalineSource = sr.ReadLine(); string namelineSource = sr.ReadLine(); Encoding encSource = sr.CurrentEncoding; sr.Close(); DeleteFirstLines(2, fileSourcePath); string textsource = File.ReadAllText(fileSourcePath); FileInfo fileNewReplace = new FileInfo(fileNewPath); FileInfo fileSourceReplace = new FileInfo(fileSourcePath); if (!Utility.FilesAreEqual(fileSourceReplace, fileNewReplace)) { Diffs.Add(fileSourcePath); } File.WriteAllText(fileNewPath, datalineNew + "\r\n" + namelineNew + "\r\n" + textnew, encnew); File.WriteAllText(fileSourcePath, datalineSource + "\r\n" + namelineSource + "\r\n" + textsource, encSource); } } else { KBDoctorOutput.Message("-- Nuevo: " + fileNewPath); } } return(Diffs); }
internal static void RemoveAttributesWithoutTable(KBModel kbmodel, IOutputService output, out List <string[]> lineswriter) { lineswriter = new List <string[]>(); // grabo todos los atributos en una colección List <Artech.Genexus.Common.Objects.Attribute> attTodos = new List <Artech.Genexus.Common.Objects.Attribute>(); foreach (Artech.Genexus.Common.Objects.Attribute a in Artech.Genexus.Common.Objects.Attribute.GetAll(kbmodel)) { attTodos.Add(a); } // voy borrando todos los atributos que estan en alguna tabla foreach (Table t in Table.GetAll(kbmodel)) { foreach (EntityReference reference in t.GetReferences(LinkType.UsedObject)) { KBObject objRef = KBObject.Get(kbmodel, reference.To); if (objRef is Artech.Genexus.Common.Objects.Attribute) { Artech.Genexus.Common.Objects.Attribute a = (Artech.Genexus.Common.Objects.Attribute)objRef; attTodos.Remove(a); } } } // TODO: Atributos en dataviews foreach (Artech.Genexus.Common.Objects.Attribute a in attTodos) { if (!Utility.AttIsSubtype(a)) { Utility.KillAttribute(a); string strRemoved = ""; try { a.Delete(); KBDoctorOutput.Message("Atribute deleted: " + a.Name); } catch (Exception e) { output.AddErrorLine("Can't delete " + a.Name + " Msg: " + e.Message); } string attNameLink = Utility.linkObject(a); //"<a href=\"gx://?Command=fa2c542d-cd46-4df2-9317-bd5899a536eb;OpenObject&name=" + a.Guid.ToString() + "\">" + a.Name + "</a>"; strRemoved = "<a href=\"gx://?Command=fa2c542d-cd46-4df2-9317-bd5899a536eb;RemoveObject&guid=" + a.Guid.ToString() + "\">Remove</a>"; string Picture = Utility.FormattedTypeAttribute(a); lineswriter.Add(new string[] { strRemoved, attNameLink, a.Description, Picture }); } } }
public static void CleanObject(KBObject obj, IOutputService output) { int totalvarremoved = 0; KBDoctorOutput.Message("Cleaning object " + obj.Name); if (obj is Transaction) { KBDoctorCore.Sources.API.CleanKBObjectVariables(obj, output); CleanAllRules(obj); CleanAllWebForm(obj); CleanAllWInForm(obj); CleanAllEvents(obj); CleanAllVars(obj); obj.SetPropertyValue(Artech.Genexus.Common.Properties.TRN.MasterPage, WebPanelReference.NoneRef); } if (obj is Procedure) { CleanAllRules(obj); CleanAllProcedurePart(obj); CleanAllConditions(obj); CleanAllVars(obj); } if (obj is WebPanel) { CleanAllRules(obj); CleanAllWebForm(obj); CleanAllEvents(obj); CleanAllConditions(obj); CleanAllVars(obj); } if (obj is WorkPanel) { CleanAllRules(obj); CleanAllWInForm(obj); CleanAllEvents(obj); CleanAllConditions(obj); CleanAllVars(obj); } try { obj.Save(); } catch (Exception e) { KBDoctorOutput.Message("Can't clean " + obj.Name + " Message: " + e.Message + "--" + e.StackTrace); } }
internal static void PrepareComparerNavigation(KnowledgeBase KB, IOutputService output) { string title = "KBDoctor - Prepare Comparer Navigation Files"; output.StartSection("KBDoctor", title); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string directoryArg = Utility.NvgComparerDirectory(KB); string fechahora = String.Format("{0:yyyy-MM-dd-HHmm}", DateTime.Now); string newDir = directoryArg + @"\NVG-" + fechahora + @"\"; try { Directory.CreateDirectory(newDir); Utility.WriteXSLTtoDir(KB); string pathspcdir = Utility.SpcDirectory(KB); string[] paths = Directory.GetDirectories(Utility.SpcDirectory(KB), "NVG", System.IO.SearchOption.AllDirectories); foreach (string d in paths) { KBDoctorOutput.Message("Procesando directorio: " + d); string generator = d.Replace(Utility.SpcDirectory(KB), ""); generator = generator.Replace("NVG_", ""); generator = @"\" + generator.Replace(@"\", "_") + "_"; generator = generator.Replace("NVG_", ""); ProcesoDir(KB, d, newDir, generator, output); } stopWatch.Stop(); // Get the elapsed time as a TimeSpan value. TimeSpan ts = stopWatch.Elapsed; // Format and display the TimeSpan value. string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10); KBDoctorOutput.Message(title + " elepsed time: " + elapsedTime); output.EndSection("KBDoctor", title, true); } catch (Exception e) { output.AddErrorLine(e.Message); } }
public static void SaveObjectsWSDL(KnowledgeBase KB, IOutputService output, bool isSource) { IEnumerable <KBObject> soapobjs = Utility.GetObjectsSOAP(KB); string urlbase = Utility.GetWebRootProperty(KB, "Default"); foreach (KBObject obj in soapobjs) { string objqname = obj.QualifiedName.ModuleName.ToLower() + ".a" + obj.QualifiedName.ObjectName.ToLower(); string path = objqname + ".aspx?wsdl"; string absolutePath = urlbase + path; var http = (HttpWebRequest)WebRequest.Create(absolutePath); var response = http.GetResponse(); var stream = response.GetResponseStream(); var sr = new StreamReader(stream); var content = sr.ReadToEnd(); string responseuri = response.ResponseUri.ToString(); string wsdldir = Utility.WsdlDir(KB, isSource); sr.Dispose(); stream.Dispose(); //response.Dispose(); if (responseuri == urlbase + path) { KBDoctorOutput.Message(absolutePath + ": OK"); string filename = wsdldir + "\\" + objqname + ".wsdl"; if (File.Exists(filename)) { File.Delete(filename); } File.AppendAllText(filename, content); } else { KBDoctorOutput.Message(absolutePath + ": Requiere login"); } } }
public static void CompareWSDLDirectories(KnowledgeBase KB, IOutputService output) { string source = Utility.WsdlDir(KB, true); string last = GetLastWSDLDir(KB); List <string> diffs = EqualWSDLDirectories(source, last, output); List <string> FilesDiff = new List <string>(); if (diffs.Count > 0) { KBDoctorOutput.Message("- Diferencias: "); foreach (string diff in diffs) { string filename = Path.GetFileName(diff); FilesDiff.Add(filename); output.AddErrorLine("- " + diff); } CopyDifferences(FilesDiff, source, last, "WSDLErrors"); } else { KBDoctorOutput.Message("- No se encontraron diferencias. "); } }
internal static void CleanKBObjectVariables(KBObject kbObj, IOutputService output, ref string recomendations) { try { VariablesPart variablesPart = null; if (!kbObj.IsCurrentVersion || kbObj.Dirty) { kbObj = KBObject.Get(kbObj.Model, kbObj.Key); } List <Variable> list = new List <Variable>(); List <IEnumerable <VariableReference> > list2 = new List <IEnumerable <VariableReference> >(); List <VariableReference> list3 = new List <VariableReference>(); string text = null; foreach (KBObjectPart current in kbObj.Parts) { if (current is VariablesPart) { variablesPart = (VariablesPart)current; } else { if (current is IHasVariableReferences) { list2.Add(((IHasVariableReferences)current).GetReferencedVariables()); } } if (current is LayoutPart && ((LayoutPart)current).Layout != null) { using (IEnumerator <IReportBand> enumerator2 = ((LayoutPart)current).Layout.ReportBands.GetEnumerator()) { while (enumerator2.MoveNext()) { IReportBand current2 = enumerator2.Current; foreach (IReportComponent current3 in current2.Controls) { if (current3 is ReportAttribute) { VariableReference item = new VariableReference(current3.Name); list3.Add(item); } } } continue; } } if (current is WebFormPart && ((WebFormPart)current).Document != null) { text = ((WebFormPart)current).Document.OuterXml; } } if (list3.Count > 0) { list2.Add(list3); } if (variablesPart != null && !variablesPart.GetPropertyValue <bool>("IsDefault")) { foreach (Variable current4 in variablesPart.Variables) { if (!current4.IsAutoDefined && !current4.IsStandard && (Artech.Genexus.Common.Properties.ATT.Dimensions_Enum)Enum.Parse(typeof(Artech.Genexus.Common.Properties.ATT.Dimensions_Enum), current4.GetPropertyValue <string>("AttNumDim")) == Artech.Genexus.Common.Properties.ATT.Dimensions_Enum.Scalar) { bool flag = false; foreach (IEnumerable <VariableReference> current5 in list2) { foreach (VariableReference current6 in current5) { if (current6.Name.Replace("&", "").Equals(current4.Name.Replace("&", ""), StringComparison.InvariantCultureIgnoreCase)) { flag = true; break; } } if (flag) { break; } } if (!flag && (text == null || !text.Contains("\"var:" + current4.Id + "\""))) { list.Add(current4); } } } if (list.Count > 0) { string text2 = ""; foreach (Variable current7 in list) { text2 = text2 + ", " + current7.Name; variablesPart.Remove(current7); } OutputMessages outputMessages = new OutputMessages(); if (kbObj.Validate(outputMessages)) { kbObj.Save(); string recommend = "Object '" + kbObj.Name + "' cleaned successfully. Variables deleted: " + text2.Substring(2); KBDoctorOutput.Message(recommend); recomendations += recommend + "<br>"; } using (IEnumerator <BaseMessage> enumerator8 = outputMessages.GetEnumerator()) { while (enumerator8.MoveNext()) { BaseMessage current8 = enumerator8.Current; if (current8.Level == MessageLevel.Error) { output.AddErrorLine("KBDoctor", current8.Text); } } } } } } catch (Exception ex) { output.AddWarningLine("KBDoctor", "Object '" + kbObj.Name + "' was not cleaned because an error ocurred: " + ex.Message); } }
internal static void RemoveObjectsNotCalled(KBModel kbmodel, IOutputService output, out List <string[]> lineswriter) { int callers; string remove = ""; bool continuar = true; lineswriter = new List <string[]>(); do { continuar = false; foreach (KBObject obj in kbmodel.Objects.GetAll()) { ICallableObject callableObject = obj as ICallableObject; if ((callableObject != null) | (obj is Artech.Genexus.Common.Objects.Attribute) | obj is Artech.Genexus.Common.Objects.Table | obj is Domain | obj is ExternalObject | obj is Image | obj is SDT) { callers = 0; foreach (EntityReference reference in obj.GetReferencesTo(LinkType.UsedObject)) { callers = callers + 1; } if (callers == 0) { if ((obj is Transaction) | obj is Table | obj is Artech.Genexus.Common.Objects.Attribute | obj is Domain | obj is Image) { remove = ""; } else { remove = "<a href=\"gx://?Command=fa2c542d-cd46-4df2-9317-bd5899a536eb;RemoveObject&guid=" + obj.Guid.ToString() + "\">Remove</a>"; } string objNameLink = Utility.linkObject(obj); string isMainstr = (Utility.isMain(obj) ? "Main" : string.Empty); string isGeneratedstr = (Utility.isGenerated(obj) ? "Yes" : string.Empty); if (!Utility.isMain(obj)) { if (remove != "") { try { obj.Delete(); KBDoctorOutput.Message("REMOVING..." + obj.Name); remove = "REMOVED!"; objNameLink = obj.Name; continuar = true; } catch (Exception e) { }; } lineswriter.Add(new string[] { obj.TypeDescriptor.Name, objNameLink, remove, isGeneratedstr, isMainstr }); } if ((obj is Transaction) && (obj.GetPropertyValue <bool>(Artech.Genexus.Common.Properties.TRN.GenerateObject))) { try { obj.SetPropertyValue(Artech.Genexus.Common.Properties.TRN.GenerateObject, false); CleanObject(obj, output); } catch (Exception e) { }; } } } } } while (continuar); }
private static void ProcesoDir(KnowledgeBase KB, string directoryArg, string newDir, string generator, IOutputService output) { string outputFile = KB.UserDirectory + @"\KBdoctorEv2.xslt"; XslTransform xslTransform = new XslTransform(); KBDoctorOutput.Message("Cargando archivo xslt: " + outputFile); xslTransform.Load(outputFile); KBDoctorOutput.Message("Archivo xslt cargado correctamente."); string fileWildcard = @"*.xml"; var searchSubDirsArg = System.IO.SearchOption.AllDirectories; string[] xFiles = System.IO.Directory.GetFiles(directoryArg, fileWildcard, searchSubDirsArg); Hashtable colisiones = new Hashtable(); HashSet <string> colisionesStr = new HashSet <string>(); //Busco colisiones en los nombres de los archivos foreach (string x in xFiles) { string filename = Path.GetFileNameWithoutExtension(x); if (!colisiones.Contains(filename)) { List <string> paths = new List <string>(); paths.Add(x); colisiones[filename] = paths; } else { List <string> paths = (List <string>)colisiones[filename]; paths.Add(x); colisiones[filename] = paths; if (!colisionesStr.Contains(filename)) { colisionesStr.Add(filename); } } } //Me quedo sólo con el archivo más nuevo y cambio el nombre de todos los demás. foreach (string name in colisionesStr) { FileInfo newestFile = null; DateTime newestDate = new DateTime(1891, 09, 28); List <string> paths = (List <string>)colisiones[name]; List <FileInfo> oldfiles = new List <FileInfo>(); foreach (string path in paths) { FileInfo file = new FileInfo(path); if (file.LastWriteTime >= newestDate) { if (newestFile != null) { oldfiles.Add(newestFile); } newestDate = file.LastWriteTime; newestFile = file; } else { oldfiles.Add(file); } } int i = 1; foreach (FileInfo fileToRename in oldfiles) { string nombre = fileToRename.DirectoryName + '\\' + Path.GetFileNameWithoutExtension(fileToRename.Name) + i.ToString() + ".oldxml"; FileInfo filerenamed = new FileInfo(nombre); if (filerenamed.Exists) { try { filerenamed.Delete(); fileToRename.MoveTo(nombre); } catch (Exception e) { } } i++; } } xFiles = System.IO.Directory.GetFiles(directoryArg, fileWildcard, searchSubDirsArg); foreach (string x in xFiles) { if (!Path.GetFileNameWithoutExtension(x).StartsWith("Gx0")) { try { string xTxt = newDir + generator + Path.GetFileNameWithoutExtension(x) + ".nvg"; string xmlstring = Utility.AddXMLHeader(x); string newXmlFile = x.Replace(".xml", ".xxx"); File.WriteAllText(newXmlFile, xmlstring); xslTransform.Transform(newXmlFile, xTxt); File.Delete(newXmlFile); } catch (Exception e) { output.AddErrorLine(e); } } } }
internal static bool CompareLastNVGDirectories(KnowledgeBase KB, IOutputService output) { try { bool isSuccess = true; string pathNvg = Path.Combine(Utility.SpcDirectory(KB), "NvgComparer"); string fileWildcard = @"*.*"; string[] Files = Directory.GetDirectories(pathNvg, fileWildcard); string[] Last2directories = GetLast2Directorys(Files, output); int cant_error = 0; if (Last2directories == null || Last2directories.Length != 2) { output.AddErrorLine("Ocurrió un error procesando los directorios de navegaciones."); output.AddErrorLine("Asegúrece de que existen al menos dos directorios con nombres en el formato válido (NVG-AAAA-MM-DD-HHMM)"); } else { KBDoctorOutput.Message("Se utilizarán los siguientes directorios para comparar:"); KBDoctorOutput.Message("-- " + Last2directories[0].ToString()); KBDoctorOutput.Message("-- " + Last2directories[1].ToString()); List <string> Diffs = EqualNavigationDirectories(Last2directories[0], Last2directories[1], output); KBDoctorOutput.Message("-- Los directorios se procesaron correctamente."); if (Diffs.Count > 0) { KBDoctorOutput.Message("-- Se encontraron diferencias en las navegaciones de los siguientes objetos:"); List <string> FilesDiff = new List <string>(); foreach (string x in Diffs) { string[] objectnametype = Utility.ReadQnameTypeFromNVGFile(x, output); string filename = Path.GetFileName(x); string objtype = objectnametype[0]; string objmodule = objectnametype[1]; string objname = objectnametype[2]; KBObjectDescriptor kbod = KBObjectDescriptor.Get(objtype); QualifiedName qname = new QualifiedName(objmodule, objname); //Null in HCIHisMo KBObject obj = KB.DesignModel.Objects.Get(kbod.Id, qname); if (obj != null) { if (obj.Timestamp <= Utility.GetDateTimeNVGDirectory(Last2directories[1].ToString())) { FilesDiff.Add(filename); if (objmodule != "") { KBDoctorOutput.Message("-- ERROR " + objmodule + '.' + objname + " fue modificado en \t\t" + obj.Timestamp.ToString()); } else { KBDoctorOutput.Message("-- ERROR " + objname + " fue modificado en \t\t" + obj.Timestamp.ToString()); } isSuccess = false; cant_error++; } else { if (objmodule != "") { KBDoctorOutput.Message("-- -- OK " + objmodule + '.' + objname + " fue modificado en \t\t" + obj.Timestamp.ToString()); } else { KBDoctorOutput.Message("-- -- OK " + objname + " fue modificado en \t\t" + obj.Timestamp.ToString()); } } } else { KBDoctorOutput.Message("-- NO SE ENCONTRO EL OBJETO: " + qname.ToString()); } } CopyDifferences(FilesDiff, Last2directories[0], Last2directories[1], "NvgErrors"); } else { DeleteDifferenceDir(KB); KBDoctorOutput.Message("No se encontraron diferencias en las navegaciones"); } } if (cant_error > 0) { output.AddErrorLine("Se encontraron " + cant_error + " errores en la comparación."); } return(isSuccess); } catch (Exception e) { KBDoctorOutput.Message(e.Message); return(false); } }
// public static void PreProcessPendingObjects(KnowledgeBase KB, IOutputService output, List<KBObject> objs, out List<string[]> lineswriter, out double tech_debt_total) { tech_debt_total = 0; const string KBDOCTOR_OUTPUTID = "KBDoctor"; output.SelectOutput(KBDOCTOR_OUTPUTID); FileIniDataParser fileIniData = new FileIniDataParser(); InitializeIniFile(KB); string filename = KB.UserDirectory + "\\KBDoctor.ini"; IniData parsedData = fileIniData.ReadFile(filename); string SectionName = "ReviewObject"; List<Tuple<KBObject, string, double>> recommended_list = new List<Tuple<KBObject, string, double>>(); List<KBObject> atts = new List<KBObject>(); foreach (KBObject obj in objs) { int obj_tech_debt = 0; int cant = 0; int valor = 1; string recommendations = ""; List<KBObject> objlist = new List<KBObject>(); objlist.Add(obj); if (Utility.isRunable(obj) && !Utility.IsGeneratedByPattern(obj)) { //Check objects with parameteres without inout if (CheckKeyInINI(parsedData, SectionName, "ParamINOUT", "true", "Check if all parameters have IN: OUT: INOUT: keywords", filename)) { Objects.ParmWOInOut(objlist, output, ref recommendations, out cant); obj_tech_debt += cant * valor; } //Clean variables not used if (CheckKeyInINI(parsedData, SectionName, "CleanUnusedVariables", "true", "Remove unused variables from objects", filename)) CleanKB.CleanKBObjectVariables(obj, output, ref recommendations); //Check commit on exit if (CheckKeyInINI(parsedData, SectionName, "CheckCommitOnExit", "true", "Check if property Commit on exit = YES", filename)) { Objects.CommitOnExit(objlist, output, ref recommendations, out cant); obj_tech_debt += cant * valor; } //Is in module if (CheckKeyInINI(parsedData, SectionName, "CheckModule", "true", "Use of modules is required", filename)) { Objects.isInModule(objlist, output, ref recommendations, out cant); obj_tech_debt += cant * valor; } //Fix variables not based in domains or attributes bool fixvar = true; if (CheckKeyInINI(parsedData, SectionName, "FixVariables", "false", "Fix variables definition, assinging Attribute or Domain", filename)) fixvar = false; //With variables not based on attributes if (CheckKeyInINI(parsedData, SectionName, "VariablesBasedAttOrDomain", "true", "Variables must be based on Attributes or Domains", filename)) { Objects.ObjectsWithVarNotBasedOnAtt(objlist, output, fixvar, ref recommendations, out cant); obj_tech_debt += cant * valor; } //Code commented if (CheckKeyInINI(parsedData, SectionName, "CodeCommented", "true", "Code commented is marked as error", filename)) { Objects.CodeCommented(objlist, output, ref recommendations, out cant); obj_tech_debt += cant * valor; } //Assign types comparer if (CheckKeyInINI(parsedData, SectionName, "AssignTypes", "true", "Check if assignments have the correct Type or Domain", filename)) { AssignTypesComprarer(KB, objlist, ref recommendations, out cant); obj_tech_debt += cant * valor; } //Parameter types comparer if (CheckKeyInINI(parsedData, SectionName, "ParameterTypes", "true", "Check if call parameters have the correct Type or Domain", filename)) { ParametersTypeComparer(KB, objlist, ref recommendations, out cant); obj_tech_debt += cant * valor; } //Empty conditional blocks if (CheckKeyInINI(parsedData, SectionName, "EmptyConditionalBlocks", "true", "Checks if exists any IF/Else block without code in it", filename)) { EmptyConditionalBlocks(KB, objlist, ref recommendations, out cant); obj_tech_debt += cant * valor; } //Constants in code if (CheckKeyInINI(parsedData, SectionName, "ConstantsInCode", "true", "Check if there are hardcoded constants", filename)) { ConstantsInCode(KB, objlist, out cant); obj_tech_debt += cant * valor; } //For eachs without when none if (CheckKeyInINI(parsedData, SectionName, "ForEachsWithoutWhenNone", "true", "Check if there is any 'ForEach' block without a 'When None' clause", filename)) ForEachsWithoutWhenNone(KB, objlist); //News without when duplicate if (CheckKeyInINI(parsedData, SectionName, "NewsWithoutWhenDuplicate", "true", "Check if there is any 'New' block without 'When Duplicate' clause", filename)) NewsWithoutWhenDuplicate(KB, objlist); if (CheckKeyInINI(parsedData, SectionName, "ProceduresCalledAsFuction", "true", "Check if the procedures are called as functions", filename)) { ProceduresCalledAsFunction(KB, objlist, ref recommendations, out cant); obj_tech_debt += cant * valor; } if (CheckKeyInINI(parsedData, SectionName, "DocumentsInWebPanels", "true", "Check if there are File management variables (and some others) in WebPanels", filename)) { DocumentsInWebPanels(KB, objlist, ref recommendations, out cant); obj_tech_debt += cant * valor; } //Check complexity metrics //maxNestLevel 6 - ComplexityLevel 30 - MaxCodeBlock 500 - parametersCount 6 bool aux; aux = CheckKeyInINI(parsedData, SectionName, "MaxNestLevel", "7", "Maximun nesting level allowed in source", filename); aux = CheckKeyInINI(parsedData, SectionName, "MaxComplexity", "30", "Maximun Complexity level allowed in sources", filename); aux = CheckKeyInINI(parsedData, SectionName, "MaxBlockSize", "500", "Maximun block of code", filename); aux = CheckKeyInINI(parsedData, SectionName, "MaxParameterCount", "6", "Maximun Number of parameters allowed in parm rule", filename); int maxNestLevel = 7; Int32.TryParse(parsedData[SectionName]["MaxNestLevel"], out maxNestLevel); int complexityLevel = 30; Int32.TryParse(parsedData[SectionName]["MaxComplexity"], out complexityLevel); int maxCodeBlock = 500; Int32.TryParse(parsedData[SectionName]["MaxBlockSize"], out maxCodeBlock); int maxParametersCount = 6; Int32.TryParse(parsedData[SectionName]["MaxParameterCount"], out maxParametersCount); int diffNestLevel; int diffcomplexityLevel; int diffCodeBlock; int diffParametersCount; Objects.CheckComplexityMetrics(obj, output, maxNestLevel, complexityLevel, maxCodeBlock, maxParametersCount, ref recommendations, out diffNestLevel, out diffcomplexityLevel, out diffCodeBlock, out diffParametersCount); obj_tech_debt += diffCodeBlock * (10/60); obj_tech_debt += diffcomplexityLevel * 1; obj_tech_debt += diffParametersCount * 1; obj_tech_debt += diffNestLevel * 1; } if (obj is Artech.Genexus.Common.Objects.Attribute && CheckKeyInINI(parsedData, SectionName, "AttributeBasedOnDomain", "true", "Attributes must be based on domains", filename)) { atts.Add(obj); //Attribute Has Domain Objects.AttributeHasDomain(objlist, output, ref recommendations, out cant); obj_tech_debt += cant * valor; } if (obj is SDT && CheckKeyInINI(parsedData, SectionName, "SDTBasedAttOrDomain", "true", "SDT items must be based on attributes or domains", filename)) { //SDTItems Has Domain Objects.SDTBasedOnAttDomain(objlist, output, ref recommendations, out cant); obj_tech_debt += cant * valor; } if (obj is Transaction && CheckKeyInINI(parsedData, SectionName, "AttributeBasedOnDomain", "true", "Attributes must be based on domains", filename)) { Objects.AttributeHasDomain(Objects.GetAttributesFromTrn((Transaction)obj), output, ref recommendations, out cant); obj_tech_debt += cant * valor; } if (recommendations != "") { Tuple<KBObject, string, double> recommend_tuple = new Tuple<KBObject, string, double>(obj, recommendations, obj_tech_debt); recommended_list.Add(recommend_tuple); } tech_debt_total += obj_tech_debt; } if (atts.Count > 0 && CheckKeyInINI(parsedData, SectionName, "AttributeWithoutTable", "true", "All attributes must be in table", filename)) { // Attributes without table Objects.AttributeWithoutTable(atts, output); } KBDoctorOutput.Message( "KBDoctor Review Object finished"); output.UnselectOutput(KBDOCTOR_OUTPUTID); output.SelectOutput("General"); lineswriter = new List<string[]>(); foreach (Tuple<KBObject, string, double> item in recommended_list) { string[] line = new string[] { Utility.linkObject(item.Item1), item.Item2, item.Item3.ToString() }; lineswriter.Add(line); } /* * Tiene todas las referencias? * Tiene calls que pueden ser UDP * Mas de un parametro de salida * Constantes en el código * Nombre "poco claro" / Descripcion "poco clara" * Si es modulo, revisar que no tenga objetos publicos no llamados * Si es modulo, revisar que no tenga objetos privados llamados desde fuera * Si es modulo, Valor de la propiedad ObjectVisibility <> Private * Atributo Varchar que debe ser char * Atributo Char que debe ser varchar * Column Title muy ancho para el ancho del atributo * Nombre del Control en pantalla por Default * Todos los eventos son invocados * */ }