diff --git a/.refactorfirst/refactor-first.json b/.refactorfirst/refactor-first.json index 176974da..a7f1cae7 100644 --- a/.refactorfirst/refactor-first.json +++ b/.refactorfirst/refactor-first.json @@ -2,24 +2,2861 @@ "project" : { "name" : "RefactorFirst", "version" : "0.11.0-SNAPSHOT", - "repoUrl" : "https://github.com/refactorfirst/RefactorFirst/blob/d7305febbb3d27e9f4eb7c078a31fbc16180e9a0/", - "baseDir" : "C:\\Code\\RefactorFirst", - "scanTimestamp" : "10/5/26, 12:57 PM", + "repoUrl" : "https://github.com/refactorfirst/RefactorFirst/blob/acc2449510653d804b12e21758d2fa873f31ac4b/", + "baseDir" : "/mnt/c/Code/refactorFirst", + "scanTimestamp" : "10/21/26, 1:12 PM", "hasAnyDisharmony" : true, "analysisFailed" : false }, "classMap" : { "graphId" : "classGraph", - "classCount" : 154, - "relationshipCount" : 300, + "classCount" : 163, + "relationshipCount" : 343, "dotThreshold" : 4000, "dotThresholdExceeded" : false, - "dot" : "strict digraph G {\nChangePronenessRanker -> ScmLogInfo [ label = \"5\" weight = \"5\" ];\nChangePronenessRanker -> GitLogReader [ label = \"2\" weight = \"2\" ];\nGitLogReader -> org_hjug_git_GitLogReader_CommitWalkStats [ label = \"4\" weight = \"4\" ];\nGitLogReader -> ScmLogInfo [ label = \"3\" weight = \"3\" ];\nMain -> ReportCommand [ label = \"1\" weight = \"1\" ];\nReportCommand -> ReportType [ label = \"1\" weight = \"1\" ];\nReportCommand -> ReportWriter [ label = \"1\" weight = \"1\" ];\nReportCommand -> SimpleHtmlReport [ label = \"4\" weight = \"4\" ];\nReportCommand -> HtmlReport [ label = \"2\" weight = \"2\" ];\nReportCommand -> JsonReportExecutor [ label = \"3\" weight = \"3\" ];\nReportCommand -> CsvReport [ label = \"3\" weight = \"3\" ];\nCodebaseGraphDTO -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"4\" weight = \"4\" ];\nCodebaseGraphDTO -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"4\" weight = \"4\" ];\nCompositeGraphBuilder -> GraphBuilderConfig [ label = \"4\" weight = \"4\" ];\nCompositeGraphBuilder -> CodebaseGraphDTO [ label = \"10\" weight = \"10\" ];\nCompositeGraphBuilder -> JavaSourceFileGraphBuilder [ label = \"3\" weight = \"3\" ];\nCompositeGraphBuilder -> KotlinSourceFileGraphBuilder [ label = \"3\" weight = \"3\" ];\nCompositeGraphBuilder -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"2\" weight = \"2\" ];\nCompositeGraphBuilder -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> SourceFileGraphBuilder [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> GraphBuilderConfig [ label = \"1\" weight = \"1\" ];\nJavaSourceFileGraphBuilder -> GraphDependencyCollector [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> JavaVisitor [ label = \"1\" weight = \"1\" ];\nJavaSourceFileGraphBuilder -> GraphMetricsCollector [ label = \"5\" weight = \"5\" ];\nJavaSourceFileGraphBuilder -> MetricsCollectingVisitor [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> AbstractDependencyVisitor [ label = \"1\" weight = \"1\" ];\nJavaSourceFileGraphBuilder -> CodebaseGraphDTO [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> Java25ParserFactory [ label = \"1\" weight = \"1\" ];\nJavaSourceFileGraphBuilder -> DisharmonyDetector [ label = \"18\" weight = \"18\" ];\nJavaSourceFileGraphBuilder -> ClassMetrics [ label = \"3\" weight = \"3\" ];\nJavaSourceFileGraphBuilder -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"3\" weight = \"3\" ];\nJavaSourceFileGraphBuilder -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"3\" weight = \"3\" ];\nKotlinSourceFileGraphBuilder -> SourceFileGraphBuilder [ label = \"2\" weight = \"2\" ];\nKotlinSourceFileGraphBuilder -> GraphBuilderConfig [ label = \"1\" weight = \"1\" ];\nKotlinSourceFileGraphBuilder -> GraphDependencyCollector [ label = \"1\" weight = \"1\" ];\nKotlinSourceFileGraphBuilder -> KotlinDependencyVisitor [ label = \"2\" weight = \"2\" ];\nKotlinSourceFileGraphBuilder -> GraphMetricsCollector [ label = \"1\" weight = \"1\" ];\nKotlinSourceFileGraphBuilder -> KotlinMetricsCollectingVisitor [ label = \"2\" weight = \"2\" ];\nKotlinSourceFileGraphBuilder -> JavaSourceFileGraphBuilder [ label = \"1\" weight = \"1\" ];\nKotlinSourceFileGraphBuilder -> CodebaseGraphDTO [ label = \"1\" weight = \"1\" ];\nSourceFileGraphBuilder -> GraphBuilderConfig [ label = \"1\" weight = \"1\" ];\nSourceFileGraphBuilder -> CodebaseGraphDTO [ label = \"1\" weight = \"1\" ];\nGraphDependencyCollector -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nClassMetrics -> MethodMetrics [ label = \"13\" weight = \"13\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony -> ClassMetrics [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony -> MethodMetrics [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\nDisharmonyDetector -> ClassMetrics [ label = \"99\" weight = \"99\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"30\" weight = \"30\" ];\nDisharmonyDetector -> DisharmonyMetric [ label = \"44\" weight = \"44\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"15\" weight = \"15\" ];\nDisharmonyDetector -> MethodMetrics [ label = \"40\" weight = \"40\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry [ label = \"5\" weight = \"5\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_FlaggedClassData [ label = \"10\" weight = \"10\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_Clone [ label = \"20\" weight = \"20\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry -> ClassMetrics [ label = \"2\" weight = \"2\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry -> MethodMetrics [ label = \"2\" weight = \"2\" ];\nDisharmonyMetric -> org_hjug_graphbuilder_metrics_DisharmonyMetric_Direction [ label = \"1\" weight = \"1\" ];\nGraphMetricsCollector -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nGraphMetricsCollector -> ClassMetrics [ label = \"33\" weight = \"33\" ];\nGraphMetricsCollector -> MethodMetrics [ label = \"10\" weight = \"10\" ];\nKotlinMetricsCollectingVisitor -> GraphMetricsCollector [ label = \"2\" weight = \"2\" ];\nKotlinMetricsCollectingVisitor -> MetricsVisitorState [ label = \"2\" weight = \"2\" ];\nKotlinMetricsCollectingVisitor -> MetricsVisitorLogic [ label = \"17\" weight = \"17\" ];\nKotlinMetricsCollectingVisitor -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot [ label = \"1\" weight = \"1\" ];\nKotlinMetricsCollectingVisitor -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot [ label = \"1\" weight = \"1\" ];\nKotlinMetricsCollectingVisitor -> ClassMetrics [ label = \"2\" weight = \"2\" ];\nMetricsCollectingVisitor -> GraphMetricsCollector [ label = \"2\" weight = \"2\" ];\nMetricsCollectingVisitor -> MetricsVisitorState [ label = \"2\" weight = \"2\" ];\nMetricsCollectingVisitor -> MetricsVisitorLogic [ label = \"10\" weight = \"10\" ];\nMetricsCollectingVisitor -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot [ label = \"1\" weight = \"1\" ];\nMetricsCollectingVisitor -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot [ label = \"1\" weight = \"1\" ];\nMetricsVisitorLogic -> MetricsVisitorState [ label = \"12\" weight = \"12\" ];\nMetricsVisitorLogic -> GraphMetricsCollector [ label = \"13\" weight = \"13\" ];\nMetricsVisitorLogic -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot [ label = \"4\" weight = \"4\" ];\nMetricsVisitorLogic -> ClassMetrics [ label = \"28\" weight = \"28\" ];\nMetricsVisitorLogic -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_OverridePredicate [ label = \"2\" weight = \"2\" ];\nMetricsVisitorLogic -> MethodMetrics [ label = \"31\" weight = \"31\" ];\nMetricsVisitorLogic -> ComplexityCalculator [ label = \"4\" weight = \"4\" ];\nMetricsVisitorLogic -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot [ label = \"3\" weight = \"3\" ];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot -> ClassMetrics [ label = \"2\" weight = \"2\" ];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot -> MethodMetrics [ label = \"2\" weight = \"2\" ];\nMetricsVisitorState -> ClassMetrics [ label = \"1\" weight = \"1\" ];\nMetricsVisitorState -> MethodMetrics [ label = \"1\" weight = \"1\" ];\nAbstractDependencyVisitor -> DependencyVisitorState [ label = \"2\" weight = \"2\" ];\nAbstractDependencyVisitor -> DependencyCollector [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_visitor_AbstractDependencyVisitor_1 -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nAbstractDependencyVisitor -> org_hjug_graphbuilder_visitor_AbstractDependencyVisitor_1 [ label = \"1\" weight = \"1\" ];\nAbstractDependencyVisitor -> BaseTypeProcessor [ label = \"1\" weight = \"1\" ];\nAbstractDependencyVisitor -> DependencyVisitorLogic [ label = \"14\" weight = \"14\" ];\nBaseTypeProcessor -> TypeDependencyExtractor [ label = \"3\" weight = \"3\" ];\nBaseTypeProcessor -> DependencyCollector [ label = \"3\" weight = \"3\" ];\nDependencyVisitorLogic -> DependencyVisitorState [ label = \"14\" weight = \"14\" ];\nDependencyVisitorLogic -> SourcePathResolver [ label = \"2\" weight = \"2\" ];\nDependencyVisitorLogic -> org_hjug_graphbuilder_visitor_DependencyVisitorLogic_ClassSnapshot [ label = \"3\" weight = \"3\" ];\nDependencyVisitorLogic -> UnattributedTypeFqnResolver [ label = \"1\" weight = \"1\" ];\nDependencyVisitorState -> BaseTypeProcessor [ label = \"2\" weight = \"2\" ];\nJavaVisitor -> AbstractDependencyVisitor [ label = \"2\" weight = \"2\" ];\nJavaVisitor -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nKotlinDependencyVisitor -> DependencyCollector [ label = \"7\" weight = \"7\" ];\nKotlinDependencyVisitor -> BaseTypeProcessor [ label = \"8\" weight = \"8\" ];\nKotlinDependencyVisitor -> DependencyVisitorState [ label = \"2\" weight = \"2\" ];\norg_hjug_graphbuilder_visitor_KotlinDependencyVisitor_1 -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nKotlinDependencyVisitor -> org_hjug_graphbuilder_visitor_KotlinDependencyVisitor_1 [ label = \"1\" weight = \"1\" ];\nKotlinDependencyVisitor -> DependencyVisitorLogic [ label = \"17\" weight = \"17\" ];\nCostBenefitCalculator -> GitLogReader [ label = \"4\" weight = \"4\" ];\nCostBenefitCalculator -> ChangePronenessRanker [ label = \"3\" weight = \"3\" ];\nCostBenefitCalculator -> CBORule [ label = \"1\" weight = \"1\" ];\nCostBenefitCalculator -> GodClass [ label = \"10\" weight = \"10\" ];\nCostBenefitCalculator -> ScmLogInfo [ label = \"16\" weight = \"16\" ];\nCostBenefitCalculator -> RankedDisharmony [ label = \"20\" weight = \"20\" ];\nCostBenefitCalculator -> CodebaseGraphDTO [ label = \"10\" weight = \"10\" ];\nCostBenefitCalculator -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"4\" weight = \"4\" ];\nCostBenefitCalculator -> GodClassRanker [ label = \"6\" weight = \"6\" ];\nCostBenefitCalculator -> DisharmonyInstance [ label = \"11\" weight = \"11\" ];\nCostBenefitCalculator -> DisharmonyRanker [ label = \"4\" weight = \"4\" ];\nCostBenefitCalculator -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"2\" weight = \"2\" ];\nCostBenefitCalculator -> Disharmony [ label = \"5\" weight = \"5\" ];\nCostBenefitCalculator -> CBOClass [ label = \"6\" weight = \"6\" ];\nCycleNode -> Disharmony [ label = \"1\" weight = \"1\" ];\nCycleNode -> ScmLogInfo [ label = \"1\" weight = \"1\" ];\nCycleRanker -> CodebaseGraphDTO [ label = \"2\" weight = \"2\" ];\nCycleRanker -> CompositeGraphBuilder [ label = \"3\" weight = \"3\" ];\nCycleRanker -> GraphBuilderConfig [ label = \"1\" weight = \"1\" ];\nCycleRanker -> RankedCycle [ label = \"7\" weight = \"7\" ];\nCycleRanker -> CircularReferenceChecker [ label = \"2\" weight = \"2\" ];\nCycleRanker -> CycleNode [ label = \"3\" weight = \"3\" ];\nRankedCycle -> CycleNode [ label = \"2\" weight = \"2\" ];\nRankedDisharmony -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\nRankedDisharmony -> GodClass [ label = \"1\" weight = \"1\" ];\nRankedDisharmony -> ScmLogInfo [ label = \"3\" weight = \"3\" ];\nRankedDisharmony -> CBOClass [ label = \"1\" weight = \"1\" ];\nRankedDisharmony -> DisharmonyInstance [ label = \"1\" weight = \"1\" ];\nCBOClass -> Disharmony [ label = \"1\" weight = \"1\" ];\nDisharmonyInstance -> Disharmony [ label = \"1\" weight = \"1\" ];\nDisharmonyInstance -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\nDisharmonyRanker -> DisharmonyInstance [ label = \"7\" weight = \"7\" ];\nDisharmonyRanker -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\nDisharmonyRanker -> org_hjug_metrics_DisharmonyRanker_ValueExtractor [ label = \"3\" weight = \"3\" ];\nDisharmonyRanker -> org_hjug_metrics_DisharmonyRanker_RankSetter [ label = \"3\" weight = \"3\" ];\nGodClass -> Disharmony [ label = \"1\" weight = \"1\" ];\nGodClassRanker -> GodClass [ label = \"18\" weight = \"18\" ];\nEdgeRemovalCalculator -> DSM [ label = \"4\" weight = \"4\" ];\nEdgeRemovalCalculator -> CircularReferenceChecker [ label = \"6\" weight = \"6\" ];\nEdgeRemovalCalculator -> EdgeToRemoveInfo [ label = \"7\" weight = \"7\" ];\nSparseIntDWGEdgeRemovalCalculator -> EdgeToRemoveInfo [ label = \"3\" weight = \"3\" ];\nFeedbackArcSetSolver -> org_hjug_feedback_arc_approximate_FeedbackArcSetResult [ label = \"2\" weight = \"2\" ];\nEdgeInfoCalculator -> EdgeInfo [ label = \"4\" weight = \"4\" ];\nMinimumFeedbackArcSetSolver -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nMinimumFeedbackArcSetSolver -> org_hjug_feedback_arc_exact_FeedbackArcSetResult [ label = \"2\" weight = \"2\" ];\nLineDigraph -> LineVertex [ label = \"68\" weight = \"68\" ];\nPageRankFAS -> SuperTypeToken [ label = \"3\" weight = \"3\" ];\nPageRankFAS -> LineDigraph [ label = \"12\" weight = \"12\" ];\nPageRankFAS -> LineVertex [ label = \"39\" weight = \"39\" ];\nCycleRemovalComputer -> CircularReferenceChecker [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> EnhancedParameterComputer [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> org_hjug_feedback_vertex_kernelized_EnhancedParameterComputer_EnhancedParameters [ label = \"4\" weight = \"4\" ];\nCycleRemovalComputer -> DirectedFeedbackVertexSetSolver [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> DirectedFeedbackVertexSetResult [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> PageRankFAS [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> CycleRemovalResult [ label = \"1\" weight = \"1\" ];\nFeedbackVertexSetSolver -> FeedbackVertexSetResult [ label = \"16\" weight = \"16\" ];\nFeedbackVertexSetSolver -> org_hjug_feedback_vertex_approximate_FeedbackVertexSetSolver_CutCandidate [ label = \"5\" weight = \"5\" ];\nDirectedFeedbackVertexSetSolver -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nDirectedFeedbackVertexSetSolver -> DirectedFeedbackVertexSetResult [ label = \"4\" weight = \"4\" ];\nDirectedFeedbackVertexSetSolver -> org_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathComputationStats [ label = \"4\" weight = \"4\" ];\nDirectedFeedbackVertexSetSolver -> org_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathContext [ label = \"1\" weight = \"1\" ];\nEnhancedParameterComputer -> TreewidthComputer [ label = \"6\" weight = \"6\" ];\nEnhancedParameterComputer -> FeedbackVertexSetComputer [ label = \"6\" weight = \"6\" ];\nEnhancedParameterComputer -> ModulatorComputer [ label = \"5\" weight = \"5\" ];\nEnhancedParameterComputer -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nEnhancedParameterComputer -> org_hjug_feedback_vertex_kernelized_EnhancedParameterComputer_EnhancedParameters [ label = \"14\" weight = \"14\" ];\nEnhancedParameterComputer -> org_hjug_feedback_vertex_kernelized_ModulatorComputer_ModulatorResult [ label = \"6\" weight = \"6\" ];\nFeedbackVertexSetComputer -> SuperTypeToken [ label = \"4\" weight = \"4\" ];\nModulatorComputer -> TreewidthComputer [ label = \"14\" weight = \"14\" ];\nModulatorComputer -> FeedbackVertexSetComputer [ label = \"5\" weight = \"5\" ];\nModulatorComputer -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nModulatorComputer -> org_hjug_feedback_vertex_kernelized_ModulatorComputer_ModulatorResult [ label = \"2\" weight = \"2\" ];\nParameterComputer -> TreewidthComputer [ label = \"7\" weight = \"7\" ];\nParameterComputer -> FeedbackVertexSetComputer [ label = \"6\" weight = \"6\" ];\nParameterComputer -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nParameterComputer -> org_hjug_feedback_vertex_kernelized_ParameterComputer_Parameters [ label = \"4\" weight = \"4\" ];\nGraphDataGenerator -> RankedDisharmony [ label = \"2\" weight = \"2\" ];\nCsvReportTask -> RefactorFirstExtension [ label = \"8\" weight = \"8\" ];\nCsvReportTask -> CsvReport [ label = \"3\" weight = \"3\" ];\nCsvReportTask -> RefactorFirstPlugin [ label = \"1\" weight = \"1\" ];\nHtmlReportTask -> RefactorFirstExtension [ label = \"13\" weight = \"13\" ];\nHtmlReportTask -> HtmlReport [ label = \"2\" weight = \"2\" ];\nHtmlReportTask -> RefactorFirstPlugin [ label = \"1\" weight = \"1\" ];\nHtmlReportTask -> SimpleHtmlReport [ label = \"1\" weight = \"1\" ];\nJsonReportTask -> RefactorFirstExtension [ label = \"3\" weight = \"3\" ];\nJsonReportTask -> JsonReportExecutor [ label = \"3\" weight = \"3\" ];\nJsonReportTask -> RefactorFirstPlugin [ label = \"1\" weight = \"1\" ];\nSimpleHtmlReportTask -> RefactorFirstExtension [ label = \"13\" weight = \"13\" ];\nSimpleHtmlReportTask -> SimpleHtmlReport [ label = \"3\" weight = \"3\" ];\nSimpleHtmlReportTask -> RefactorFirstPlugin [ label = \"1\" weight = \"1\" ];\nMavenReportOutputDirectory -> ReportWriter [ label = \"1\" weight = \"1\" ];\nRefactorFirstHtmlReport -> HtmlReport [ label = \"2\" weight = \"2\" ];\nRefactorFirstHtmlReport -> MavenReportOutputDirectory [ label = \"1\" weight = \"1\" ];\nRefactorFirstHtmlReport -> SimpleHtmlReport [ label = \"1\" weight = \"1\" ];\nRefactorFirstMavenCsvReport -> CsvReport [ label = \"3\" weight = \"3\" ];\nRefactorFirstMavenCsvReport -> MavenReportOutputDirectory [ label = \"1\" weight = \"1\" ];\nRefactorFirstMavenJsonGenerator -> JsonGenerator [ label = \"3\" weight = \"3\" ];\nRefactorFirstMavenJsonReport -> JsonReportExecutor [ label = \"3\" weight = \"3\" ];\nRefactorFirstMavenJsonReport -> MavenReportOutputDirectory [ label = \"1\" weight = \"1\" ];\nRefactorFirstMavenReport -> HtmlReport [ label = \"2\" weight = \"2\" ];\nRefactorFirstMavenReport -> SimpleHtmlReport [ label = \"1\" weight = \"1\" ];\nRefactorFirstSimpleHtmlReport -> SimpleHtmlReport [ label = \"3\" weight = \"3\" ];\nRefactorFirstSimpleHtmlReport -> MavenReportOutputDirectory [ label = \"1\" weight = \"1\" ];\nCsvReport -> GitLogReader [ label = \"4\" weight = \"4\" ];\nCsvReport -> ReportWriter [ label = \"3\" weight = \"3\" ];\nCsvReport -> RankedDisharmony [ label = \"3\" weight = \"3\" ];\nCsvReport -> CostBenefitCalculator [ label = \"5\" weight = \"5\" ];\nHtmlReport -> SimpleHtmlReport [ label = \"9\" weight = \"9\" ];\nHtmlReport -> RankedDisharmony [ label = \"1\" weight = \"1\" ];\nHtmlReport -> GraphDataGenerator [ label = \"5\" weight = \"5\" ];\nHtmlReport -> CodebaseGraphDTO [ label = \"17\" weight = \"17\" ];\nHtmlReport -> RankedCycle [ label = \"3\" weight = \"3\" ];\nJsonReport -> JsonReportDisharmonyEntry [ label = \"1\" weight = \"1\" ];\nJsonReportDisharmonyEntry -> RankedDisharmony [ label = \"1\" weight = \"1\" ];\nJsonReportExecutor -> CostBenefitCalculator [ label = \"5\" weight = \"5\" ];\nJsonReportExecutor -> RankedDisharmony [ label = \"2\" weight = \"2\" ];\nJsonReportExecutor -> JsonReportDisharmonyEntry [ label = \"2\" weight = \"2\" ];\nJsonReportExecutor -> JsonReport [ label = \"3\" weight = \"3\" ];\nJsonReportExecutor -> ReportWriter [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> HtmlReport [ label = \"4\" weight = \"4\" ];\nJsonGenerator -> RefactorFirstReportDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> CodebaseGraphDTO [ label = \"5\" weight = \"5\" ];\nJsonGenerator -> GitLogReader [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> CycleRanker [ label = \"5\" weight = \"5\" ];\nJsonGenerator -> RankedCycle [ label = \"3\" weight = \"3\" ];\nJsonGenerator -> CycleRemovalComputer [ label = \"4\" weight = \"4\" ];\nJsonGenerator -> CycleRemovalResult [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> RankedDisharmony [ label = \"10\" weight = \"10\" ];\nJsonGenerator -> CostBenefitCalculator [ label = \"6\" weight = \"6\" ];\nJsonGenerator -> org_hjug_refactorfirst_report_SimpleHtmlReport_DisharmonySpec [ label = \"17\" weight = \"17\" ];\nJsonGenerator -> DisharmonyInstance [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> SimpleHtmlReport [ label = \"22\" weight = \"22\" ];\nJsonGenerator -> ProjectMetadataDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> GraphVisualDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> ClassRelationshipDTO [ label = \"6\" weight = \"6\" ];\nJsonGenerator -> ClassRelationshipsToRemoveDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> PackageRelationshipDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> PackageRelationshipsToRemoveDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> DisharmonySectionDTO [ label = \"3\" weight = \"3\" ];\nJsonGenerator -> CycleSummaryDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> LargestCycleDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> CycleBreakdownRowDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> ClassCyclesDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> ChartJsBubbleDTO [ label = \"3\" weight = \"3\" ];\nJsonGenerator -> DisharmonyChartDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> DisharmonyMetric [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> DisharmonyTableRowDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> DisharmonyTableCellDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> DisharmonyTableDTO [ label = \"1\" weight = \"1\" ];\nClassCyclesDTO -> CycleSummaryDTO [ label = \"2\" weight = \"2\" ];\nClassCyclesDTO -> LargestCycleDTO [ label = \"1\" weight = \"1\" ];\nClassRelationshipsToRemoveDTO -> ClassRelationshipDTO [ label = \"2\" weight = \"2\" ];\nDisharmonyChartDTO -> ChartJsBubbleDTO [ label = \"2\" weight = \"2\" ];\nDisharmonySectionDTO -> DisharmonyChartDTO [ label = \"1\" weight = \"1\" ];\nDisharmonySectionDTO -> DisharmonyTableDTO [ label = \"1\" weight = \"1\" ];\nDisharmonyTableDTO -> DisharmonyTableRowDTO [ label = \"2\" weight = \"2\" ];\nDisharmonyTableRowDTO -> DisharmonyTableCellDTO [ label = \"2\" weight = \"2\" ];\nLargestCycleDTO -> CycleBreakdownRowDTO [ label = \"2\" weight = \"2\" ];\nPackageRelationshipDTO -> ClassRelationshipDTO [ label = \"2\" weight = \"2\" ];\nPackageRelationshipsToRemoveDTO -> PackageRelationshipDTO [ label = \"2\" weight = \"2\" ];\nRefactorFirstReportDTO -> ProjectMetadataDTO [ label = \"1\" weight = \"1\" ];\nRefactorFirstReportDTO -> GraphVisualDTO [ label = \"2\" weight = \"2\" ];\nRefactorFirstReportDTO -> ClassRelationshipsToRemoveDTO [ label = \"1\" weight = \"1\" ];\nRefactorFirstReportDTO -> PackageRelationshipsToRemoveDTO [ label = \"1\" weight = \"1\" ];\nRefactorFirstReportDTO -> DisharmonySectionDTO [ label = \"2\" weight = \"2\" ];\nRefactorFirstReportDTO -> ClassCyclesDTO [ label = \"1\" weight = \"1\" ];\nReportWriter -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"3\" weight = \"3\" ];\nReportWriter -> org_hjug_refactorfirst_report_ReportWriter_ReportWriteException [ label = \"3\" weight = \"3\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl [ label = \"1\" weight = \"1\" color = \"red\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps [ label = \"1\" weight = \"1\" color = \"red\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl -> ReportWriter [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps -> ReportWriter [ label = \"1\" weight = \"1\" ];\nSimpleHtmlReport -> org_hjug_refactorfirst_report_SimpleHtmlReport_DisharmonySpec [ label = \"34\" weight = \"34\" ];\nSimpleHtmlReport -> ReportWriter [ label = \"1\" weight = \"1\" ];\nSimpleHtmlReport -> GitLogReader [ label = \"5\" weight = \"5\" ];\nSimpleHtmlReport -> CycleRanker [ label = \"5\" weight = \"5\" ];\nSimpleHtmlReport -> RankedCycle [ label = \"10\" weight = \"10\" ];\nSimpleHtmlReport -> CodebaseGraphDTO [ label = \"13\" weight = \"13\" ];\nSimpleHtmlReport -> CycleRemovalComputer [ label = \"4\" weight = \"4\" ];\nSimpleHtmlReport -> CycleRemovalResult [ label = \"2\" weight = \"2\" ];\nSimpleHtmlReport -> RankedDisharmony [ label = \"16\" weight = \"16\" ];\nSimpleHtmlReport -> CostBenefitCalculator [ label = \"6\" weight = \"6\" ];\nSimpleHtmlReport -> DisharmonyInstance [ label = \"1\" weight = \"1\" ];\nSimpleHtmlReport -> DisharmonyMetric [ label = \"3\" weight = \"3\" ];\nConsole -> io_confluent_ksql_cli_console_Console_RowCaptor [ label = \"4\" weight = \"4\" ];\nConsole -> io_confluent_ksql_cli_console_Console_NoOpRowCaptor [ label = \"1\" weight = \"1\" ];\nConsole -> io_confluent_ksql_cli_console_Console_CliCmdExecutor [ label = \"4\" weight = \"4\" ];\nio_confluent_ksql_cli_console_Console_NoOpRowCaptor -> io_confluent_ksql_cli_console_Console_RowCaptor [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_visitor_AbstractDependencyVisitor_1 [ label=\"AbstractDependencyVisitor$1\"];\nCycleSummaryDTO [];\nJsonReport [];\nDisharmonyTableCellDTO [];\nEdgeRemovalCalculator [];\nSimpleHtmlReport [];\nLineDigraph [];\nCsvReportTask [];\nRefactorFirstExtension [];\norg_hjug_refactorfirst_report_SimpleHtmlReport_DisharmonySpec [ label=\"SimpleHtmlReport$DisharmonySpec\"];\nGraphMetricsCollector [];\nDisharmonyInstance [];\norg_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathContext [ label=\"DirectedFeedbackVertexSetSolver$PathContext\"];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot [ label=\"MetricsVisitorLogic$ClassStateSnapshot\"];\nDisharmonySectionDTO [];\nMavenReportOutputDirectory [];\nPackageRelationshipsToRemoveDTO [];\nCompositeGraphBuilder [];\nPackageRelationshipDTO [];\nMetricsCollectingVisitor [];\nKotlinSourceFileGraphBuilder [];\nMethodMetrics [];\nCodebaseGraphDTO [];\nRankedDisharmony [];\nFeedbackVertexSetResult [];\nRefactorFirstMavenJsonReport [];\nCycleRemovalComputer [];\nJsonReportTask [];\nDSM [];\nJsonReportDisharmonyEntry [];\norg_hjug_graphbuilder_metrics_DisharmonyMetric_Direction [ label=\"DisharmonyMetric$Direction\"];\nio_confluent_ksql_cli_console_Console_RowCaptor [ label=\"Console$RowCaptor\"];\nCycleBreakdownRowDTO [];\nDisharmonyDetector [];\nCircularReferenceChecker [];\nFeedbackArcSetSolver [];\nCycleRemovalResult [];\norg_hjug_refactorfirst_report_ReportWriter_ReportWriteException [ label=\"ReportWriter$ReportWriteException\"];\nAbstractDependencyVisitor [];\nJava25ParserFactory [];\nProjectMetadataDTO [];\norg_hjug_feedback_vertex_kernelized_ParameterComputer_Parameters [ label=\"ParameterComputer$Parameters\"];\nLargestCycleDTO [];\nRankedCycle [];\nClassRelationshipDTO [];\nDisharmonyRanker [];\norg_hjug_git_GitLogReader_CommitWalkStats [ label=\"GitLogReader$CommitWalkStats\"];\nGraphVisualDTO [];\nDisharmonyTableRowDTO [];\nChangePronenessRanker [];\nScmLogInfo [];\nKotlinMetricsCollectingVisitor [];\nEdgeToRemoveInfo [];\nDirectedFeedbackVertexSetSolver [];\nGraphBuilderConfig [];\nMinimumFeedbackArcSetSolver [];\norg_hjug_graphbuilder_visitor_DependencyVisitorLogic_ClassSnapshot [ label=\"DependencyVisitorLogic$ClassSnapshot\"];\nRefactorFirstMavenReport [];\nEdgeInfoCalculator [];\nRefactorFirstMavenJsonGenerator [];\nCycleRanker [];\nReportCommand [];\nDisharmonyChartDTO [];\nRefactorFirstPlugin [];\nDependencyCollector [];\nCostBenefitCalculator [];\nEdgeInfo [];\nGitLogReader [];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_OverridePredicate [ label=\"MetricsVisitorLogic$OverridePredicate\"];\nGraphDependencyCollector [];\nDependencyVisitorLogic [];\nDisharmony [];\nio_confluent_ksql_cli_console_Console_NoOpRowCaptor [ label=\"Console$NoOpRowCaptor\"];\nClassMetrics [];\nSparseIntDWGEdgeRemovalCalculator [];\nRefactorFirstSimpleHtmlReport [];\nClassRelationshipsToRemoveDTO [];\nCsvReport [];\nDisharmonyTableDTO [];\nJsonGenerator [];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_FlaggedClassData [ label=\"DisharmonyDetector$FlaggedClassData\"];\norg_hjug_metrics_DisharmonyRanker_RankSetter [ label=\"DisharmonyRanker$RankSetter\"];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label=\"ReportWriter$SecureDirectoryOps\"];\nChartJsBubbleDTO [];\nHtmlReport [];\nDisharmonyMetric [];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot [ label=\"MetricsVisitorLogic$MethodStateSnapshot\"];\norg_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathComputationStats [ label=\"DirectedFeedbackVertexSetSolver$PathComputationStats\"];\nLineVertex [];\norg_hjug_feedback_vertex_kernelized_ModulatorComputer_ModulatorResult [ label=\"ModulatorComputer$ModulatorResult\"];\nGodClass [];\nDirectedFeedbackVertexSetResult [];\nRefactorFirstReportDTO [];\nio_confluent_ksql_cli_console_Console_CliCmdExecutor [ label=\"Console$CliCmdExecutor\"];\nKotlinDependencyVisitor [];\norg_hjug_feedback_vertex_approximate_FeedbackVertexSetSolver_CutCandidate [ label=\"FeedbackVertexSetSolver$CutCandidate\"];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_Clone [ label=\"DisharmonyDetector$Clone\"];\nCBOClass [];\nMain [];\nJavaSourceFileGraphBuilder [];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl [ label=\"ReportWriter$SecureDirectoryOpsImpl\"];\nGodClassRanker [];\norg_hjug_graphbuilder_visitor_KotlinDependencyVisitor_1 [ label=\"KotlinDependencyVisitor$1\"];\norg_hjug_feedback_vertex_kernelized_EnhancedParameterComputer_EnhancedParameters [ label=\"EnhancedParameterComputer$EnhancedParameters\"];\nConsole [];\nCycleNode [];\nFeedbackVertexSetComputer [];\nCBORule [];\nReportType [];\nParameterComputer [];\nComplexityCalculator [];\nRefactorFirstMavenCsvReport [];\nReportWriter [ color=red style=filled];\nMetricsVisitorLogic [];\norg_hjug_metrics_DisharmonyRanker_ValueExtractor [ label=\"DisharmonyRanker$ValueExtractor\"];\nMetricsVisitorState [];\nTypeDependencyExtractor [];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label=\"DisharmonyDetector$ClassDisharmony\"];\nHtmlReportTask [];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry [ label=\"DisharmonyDetector$MethodEntry\"];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps [ label=\"ReportWriter$FallbackDirectoryOps\"];\norg_hjug_feedback_arc_approximate_FeedbackArcSetResult [ label=\"FeedbackArcSetResult\"];\nJavaVisitor [];\nJsonReportExecutor [];\nBaseTypeProcessor [];\nEnhancedParameterComputer [];\nFeedbackVertexSetSolver [];\nGraphDataGenerator [];\nDependencyVisitorState [];\norg_hjug_feedback_arc_exact_FeedbackArcSetResult [ label=\"FeedbackArcSetResult\"];\nUnattributedTypeFqnResolver [];\nSourceFileGraphBuilder [];\nSuperTypeToken [];\nPageRankFAS [];\nSourcePathResolver [];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label=\"DisharmonyDetector$MethodDisharmony\"];\nSimpleHtmlReportTask [];\nRefactorFirstHtmlReport [];\nClassCyclesDTO [];\nTreewidthComputer [];\nModulatorComputer [];\n}", + "hierarchy" : { + "packages" : [ { + "name" : "io.confluent.ksql.cli.console", + "id" : "cluster_8add44c30cc266830b504c3d", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "io.confluent.ksql.cli.console.Console", + "id" : "Console", + "label" : "Console", + "path" : "test-resources/src/main/resources/Console.java", + "markedForRemoval" : false + }, { + "fqn" : "io.confluent.ksql.cli.console.Console$CliCmdExecutor", + "id" : "io_confluent_ksql_cli_console_Console_CliCmdExecutor", + "label" : "Console$CliCmdExecutor", + "path" : "test-resources/src/main/resources/Console.java", + "markedForRemoval" : false + }, { + "fqn" : "io.confluent.ksql.cli.console.Console$NoOpRowCaptor", + "id" : "io_confluent_ksql_cli_console_Console_NoOpRowCaptor", + "label" : "Console$NoOpRowCaptor", + "path" : "test-resources/src/main/resources/Console.java", + "markedForRemoval" : false + }, { + "fqn" : "io.confluent.ksql.cli.console.Console$RowCaptor", + "id" : "io_confluent_ksql_cli_console_Console_RowCaptor", + "label" : "Console$RowCaptor", + "path" : "test-resources/src/main/resources/Console.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug", + "id" : "cluster_8470465d943ffd5150e2d522", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ { + "name" : "org.hjug.cbc", + "id" : "cluster_bfb0d6f0cb59390b479b08a1", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : true, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.cbc.CostBenefitCalculator", + "id" : "CostBenefitCalculator", + "label" : "CostBenefitCalculator", + "path" : "cost-benefit-calculator/src/main/java/org/hjug/cbc/CostBenefitCalculator.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.cbc.CycleNode", + "id" : "CycleNode", + "label" : "CycleNode", + "path" : "cost-benefit-calculator/src/main/java/org/hjug/cbc/CycleNode.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.cbc.CycleRanker", + "id" : "CycleRanker", + "label" : "CycleRanker", + "path" : "cost-benefit-calculator/src/main/java/org/hjug/cbc/CycleRanker.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.cbc.RankedCycle", + "id" : "RankedCycle", + "label" : "RankedCycle", + "path" : "cost-benefit-calculator/src/main/java/org/hjug/cbc/RankedCycle.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.cbc.RankedDisharmony", + "id" : "RankedDisharmony", + "label" : "RankedDisharmony", + "path" : "cost-benefit-calculator/src/main/java/org/hjug/cbc/RankedDisharmony.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.dsm", + "id" : "cluster_6da3c08ea2d561edab77673f", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.dsm.CircularReferenceChecker", + "id" : "CircularReferenceChecker", + "label" : "CircularReferenceChecker", + "path" : "graph-algorithms/src/main/java/org/hjug/dsm/CircularReferenceChecker.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.dsm.DSM", + "id" : "DSM", + "label" : "DSM", + "path" : "graph-algorithms/src/main/java/org/hjug/dsm/DSM.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.dsm.EdgeRemovalCalculator", + "id" : "EdgeRemovalCalculator", + "label" : "EdgeRemovalCalculator", + "path" : "graph-algorithms/src/main/java/org/hjug/dsm/EdgeRemovalCalculator.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.dsm.EdgeToRemoveInfo", + "id" : "EdgeToRemoveInfo", + "label" : "EdgeToRemoveInfo", + "path" : "graph-algorithms/src/main/java/org/hjug/dsm/EdgeToRemoveInfo.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.dsm.SparseIntDWGEdgeRemovalCalculator", + "id" : "SparseIntDWGEdgeRemovalCalculator", + "label" : "SparseIntDWGEdgeRemovalCalculator", + "path" : "graph-algorithms/src/main/java/org/hjug/dsm/SparseIntDWGEdgeRemovalCalculator.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.feedback", + "id" : "cluster_0b6cea3e7e0dde98e8d142c3", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ { + "name" : "org.hjug.feedback.arc", + "id" : "cluster_291a9b47e500445b847479b7", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ { + "name" : "org.hjug.feedback.arc.approximate", + "id" : "cluster_3a3f2fa13f4a03ff432fb290", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.feedback.arc.approximate.FeedbackArcSetResult", + "id" : "org_hjug_feedback_arc_approximate_FeedbackArcSetResult", + "label" : "FeedbackArcSetResult", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/approximate/FeedbackArcSetResult.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.arc.approximate.FeedbackArcSetSolver", + "id" : "FeedbackArcSetSolver", + "label" : "FeedbackArcSetSolver", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/approximate/FeedbackArcSetSolver.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.feedback.arc.exact", + "id" : "cluster_5770287cc40afd5bd6812d59", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.feedback.arc.exact.FeedbackArcSetResult", + "id" : "org_hjug_feedback_arc_exact_FeedbackArcSetResult", + "label" : "FeedbackArcSetResult", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/FeedbackArcSetResult.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.arc.exact.MinimumFeedbackArcSetSolver", + "id" : "MinimumFeedbackArcSetSolver", + "label" : "MinimumFeedbackArcSetSolver", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.feedback.arc.pageRank", + "id" : "cluster_d30a7a8d892c5e6113a07e84", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.feedback.arc.pageRank.LineDigraph", + "id" : "LineDigraph", + "label" : "LineDigraph", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/LineDigraph.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.arc.pageRank.LineVertex", + "id" : "LineVertex", + "label" : "LineVertex", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.arc.pageRank.PageRankFAS", + "id" : "PageRankFAS", + "label" : "PageRankFAS", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java", + "markedForRemoval" : false + } ] + } ], + "classes" : [ { + "fqn" : "org.hjug.feedback.arc.EdgeInfo", + "id" : "EdgeInfo", + "label" : "EdgeInfo", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/EdgeInfo.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.arc.EdgeInfoCalculator", + "id" : "EdgeInfoCalculator", + "label" : "EdgeInfoCalculator", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/EdgeInfoCalculator.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.feedback.vertex", + "id" : "cluster_4a03f850876152381c5e9663", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ { + "name" : "org.hjug.feedback.vertex.approximate", + "id" : "cluster_944f1b3497849d742c8c554f", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.feedback.vertex.approximate.FeedbackVertexSetResult", + "id" : "FeedbackVertexSetResult", + "label" : "FeedbackVertexSetResult", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/approximate/FeedbackVertexSetResult.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.vertex.approximate.FeedbackVertexSetSolver", + "id" : "FeedbackVertexSetSolver", + "label" : "FeedbackVertexSetSolver", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/approximate/FeedbackVertexSetSolver.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.vertex.approximate.FeedbackVertexSetSolver$CutCandidate", + "id" : "org_hjug_feedback_vertex_approximate_FeedbackVertexSetSolver_CutCandidate", + "label" : "FeedbackVertexSetSolver$CutCandidate", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/approximate/FeedbackVertexSetSolver.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.feedback.vertex.kernelized", + "id" : "cluster_d2f1dd27b2e43b88238a4c05", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.feedback.vertex.kernelized.DirectedFeedbackVertexSetResult", + "id" : "DirectedFeedbackVertexSetResult", + "label" : "DirectedFeedbackVertexSetResult", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetResult.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.vertex.kernelized.DirectedFeedbackVertexSetSolver", + "id" : "DirectedFeedbackVertexSetSolver", + "label" : "DirectedFeedbackVertexSetSolver", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.vertex.kernelized.DirectedFeedbackVertexSetSolver$PathComputationStats", + "id" : "org_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathComputationStats", + "label" : "DirectedFeedbackVertexSetSolver$PathComputationStats", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.vertex.kernelized.DirectedFeedbackVertexSetSolver$PathContext", + "id" : "org_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathContext", + "label" : "DirectedFeedbackVertexSetSolver$PathContext", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.vertex.kernelized.EnhancedParameterComputer", + "id" : "EnhancedParameterComputer", + "label" : "EnhancedParameterComputer", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/EnhancedParameterComputer.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.vertex.kernelized.EnhancedParameterComputer$EnhancedParameters", + "id" : "org_hjug_feedback_vertex_kernelized_EnhancedParameterComputer_EnhancedParameters", + "label" : "EnhancedParameterComputer$EnhancedParameters", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/EnhancedParameterComputer.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.vertex.kernelized.FeedbackVertexSetComputer", + "id" : "FeedbackVertexSetComputer", + "label" : "FeedbackVertexSetComputer", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/FeedbackVertexSetComputer.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.vertex.kernelized.ModulatorComputer", + "id" : "ModulatorComputer", + "label" : "ModulatorComputer", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.vertex.kernelized.ModulatorComputer$ModulatorResult", + "id" : "org_hjug_feedback_vertex_kernelized_ModulatorComputer_ModulatorResult", + "label" : "ModulatorComputer$ModulatorResult", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.vertex.kernelized.ParameterComputer", + "id" : "ParameterComputer", + "label" : "ParameterComputer", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ParameterComputer.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.vertex.kernelized.ParameterComputer$Parameters", + "id" : "org_hjug_feedback_vertex_kernelized_ParameterComputer_Parameters", + "label" : "ParameterComputer$Parameters", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ParameterComputer.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.vertex.kernelized.TreewidthComputer", + "id" : "TreewidthComputer", + "label" : "TreewidthComputer", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java", + "markedForRemoval" : false + } ] + } ], + "classes" : [ ] + } ], + "classes" : [ { + "fqn" : "org.hjug.feedback.CycleRemovalComputer", + "id" : "CycleRemovalComputer", + "label" : "CycleRemovalComputer", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/CycleRemovalComputer.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.CycleRemovalResult", + "id" : "CycleRemovalResult", + "label" : "CycleRemovalResult", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/CycleRemovalResult.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.feedback.SuperTypeToken", + "id" : "SuperTypeToken", + "label" : "SuperTypeToken", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/SuperTypeToken.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.gdg", + "id" : "cluster_e16f87ed4cbaa8972b66b80b", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.gdg.GraphDataGenerator", + "id" : "GraphDataGenerator", + "label" : "GraphDataGenerator", + "path" : "graph-data-generator/src/main/java/org/hjug/gdg/GraphDataGenerator.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.git", + "id" : "cluster_cc2439ece2ff219a79eb369d", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.git.ChangePronenessRanker", + "id" : "ChangePronenessRanker", + "label" : "ChangePronenessRanker", + "path" : "change-proneness-ranker/src/main/java/org/hjug/git/ChangePronenessRanker.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.git.GitLogReader", + "id" : "GitLogReader", + "label" : "GitLogReader", + "path" : "change-proneness-ranker/src/main/java/org/hjug/git/GitLogReader.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.git.GitLogReader$CommitWalkStats", + "id" : "org_hjug_git_GitLogReader_CommitWalkStats", + "label" : "GitLogReader$CommitWalkStats", + "path" : "change-proneness-ranker/src/main/java/org/hjug/git/GitLogReader.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.git.ScmLogInfo", + "id" : "ScmLogInfo", + "label" : "ScmLogInfo", + "path" : "change-proneness-ranker/src/main/java/org/hjug/git/ScmLogInfo.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.gradlereport", + "id" : "cluster_c28460328a6700365ccc109d", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.gradlereport.CsvReportTask", + "id" : "CsvReportTask", + "label" : "CsvReportTask", + "path" : "refactor-first-gradle-plugin/src/main/java/org/hjug/gradlereport/CsvReportTask.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.gradlereport.HtmlReportTask", + "id" : "HtmlReportTask", + "label" : "HtmlReportTask", + "path" : "refactor-first-gradle-plugin/src/main/java/org/hjug/gradlereport/HtmlReportTask.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.gradlereport.JsonReportTask", + "id" : "JsonReportTask", + "label" : "JsonReportTask", + "path" : "refactor-first-gradle-plugin/src/main/java/org/hjug/gradlereport/JsonReportTask.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.gradlereport.RefactorFirstExtension", + "id" : "RefactorFirstExtension", + "label" : "RefactorFirstExtension", + "path" : "refactor-first-gradle-plugin/src/main/java/org/hjug/gradlereport/RefactorFirstExtension.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.gradlereport.RefactorFirstPlugin", + "id" : "RefactorFirstPlugin", + "label" : "RefactorFirstPlugin", + "path" : "refactor-first-gradle-plugin/src/main/java/org/hjug/gradlereport/RefactorFirstPlugin.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.gradlereport.SimpleHtmlReportTask", + "id" : "SimpleHtmlReportTask", + "label" : "SimpleHtmlReportTask", + "path" : "refactor-first-gradle-plugin/src/main/java/org/hjug/gradlereport/SimpleHtmlReportTask.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.graphbuilder", + "id" : "cluster_275b39592e996f9bc7d2bab4", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : true, + "path" : "", + "children" : [ { + "name" : "org.hjug.graphbuilder.graphbuilder", + "id" : "cluster_98c578ab6c4dd833f53d3aee", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.graphbuilder.graphbuilder.Java25ParserFactory", + "id" : "Java25ParserFactory", + "label" : "Java25ParserFactory", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/graphbuilder/Java25ParserFactory.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.graphbuilder.JavaSourceFileGraphBuilder", + "id" : "JavaSourceFileGraphBuilder", + "label" : "JavaSourceFileGraphBuilder", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/graphbuilder/JavaSourceFileGraphBuilder.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.graphbuilder.KotlinSourceFileGraphBuilder", + "id" : "KotlinSourceFileGraphBuilder", + "label" : "KotlinSourceFileGraphBuilder", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/graphbuilder/KotlinSourceFileGraphBuilder.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.graphbuilder.SourceFileGraphBuilder", + "id" : "SourceFileGraphBuilder", + "label" : "SourceFileGraphBuilder", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/graphbuilder/SourceFileGraphBuilder.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.graphbuilder.metrics", + "id" : "cluster_179967d6e66ef95e5ec582dc", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.graphbuilder.metrics.ClassMetrics", + "id" : "ClassMetrics", + "label" : "ClassMetrics", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ClassMetrics.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.ComplexityCalculator", + "id" : "ComplexityCalculator", + "label" : "ComplexityCalculator", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ComplexityCalculator.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.DisharmonyDetector", + "id" : "DisharmonyDetector", + "label" : "DisharmonyDetector", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.DisharmonyDetector$ClassDisharmony", + "id" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony", + "label" : "DisharmonyDetector$ClassDisharmony", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.DisharmonyDetector$Clone", + "id" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_Clone", + "label" : "DisharmonyDetector$Clone", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.DisharmonyDetector$FlaggedClassData", + "id" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_FlaggedClassData", + "label" : "DisharmonyDetector$FlaggedClassData", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.DisharmonyDetector$MethodDisharmony", + "id" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony", + "label" : "DisharmonyDetector$MethodDisharmony", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.DisharmonyDetector$MethodEntry", + "id" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry", + "label" : "DisharmonyDetector$MethodEntry", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.DisharmonyMetric", + "id" : "DisharmonyMetric", + "label" : "DisharmonyMetric", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyMetric.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.DisharmonyMetric$Direction", + "id" : "org_hjug_graphbuilder_metrics_DisharmonyMetric_Direction", + "label" : "DisharmonyMetric$Direction", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyMetric.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.GraphMetricsCollector", + "id" : "GraphMetricsCollector", + "label" : "GraphMetricsCollector", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.KotlinMetricsCollectingVisitor", + "id" : "KotlinMetricsCollectingVisitor", + "label" : "KotlinMetricsCollectingVisitor", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/KotlinMetricsCollectingVisitor.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.MethodMetrics", + "id" : "MethodMetrics", + "label" : "MethodMetrics", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MethodMetrics.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.MetricsCollectingVisitor", + "id" : "MetricsCollectingVisitor", + "label" : "MetricsCollectingVisitor", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsCollectingVisitor.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.MetricsVisitorLogic", + "id" : "MetricsVisitorLogic", + "label" : "MetricsVisitorLogic", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.MetricsVisitorLogic$ClassStateSnapshot", + "id" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot", + "label" : "MetricsVisitorLogic$ClassStateSnapshot", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.MetricsVisitorLogic$MethodStateSnapshot", + "id" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot", + "label" : "MetricsVisitorLogic$MethodStateSnapshot", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.MetricsVisitorLogic$OverridePredicate", + "id" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_OverridePredicate", + "label" : "MetricsVisitorLogic$OverridePredicate", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.metrics.MetricsVisitorState", + "id" : "MetricsVisitorState", + "label" : "MetricsVisitorState", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorState.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.graphbuilder.visitor", + "id" : "cluster_d36e09db80f0e2bbc4ffd5c7", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.graphbuilder.visitor.AbstractDependencyVisitor", + "id" : "AbstractDependencyVisitor", + "label" : "AbstractDependencyVisitor", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/AbstractDependencyVisitor.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.visitor.AbstractDependencyVisitor$1", + "id" : "org_hjug_graphbuilder_visitor_AbstractDependencyVisitor_1", + "label" : "AbstractDependencyVisitor$1", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/AbstractDependencyVisitor.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.visitor.BaseTypeProcessor", + "id" : "BaseTypeProcessor", + "label" : "BaseTypeProcessor", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/BaseTypeProcessor.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.visitor.DependencyVisitorLogic", + "id" : "DependencyVisitorLogic", + "label" : "DependencyVisitorLogic", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.visitor.DependencyVisitorLogic$ClassSnapshot", + "id" : "org_hjug_graphbuilder_visitor_DependencyVisitorLogic_ClassSnapshot", + "label" : "DependencyVisitorLogic$ClassSnapshot", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.visitor.DependencyVisitorState", + "id" : "DependencyVisitorState", + "label" : "DependencyVisitorState", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorState.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.visitor.JavaVisitor", + "id" : "JavaVisitor", + "label" : "JavaVisitor", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/JavaVisitor.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.visitor.KotlinDependencyVisitor", + "id" : "KotlinDependencyVisitor", + "label" : "KotlinDependencyVisitor", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/KotlinDependencyVisitor.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.visitor.KotlinDependencyVisitor$1", + "id" : "org_hjug_graphbuilder_visitor_KotlinDependencyVisitor_1", + "label" : "KotlinDependencyVisitor$1", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/KotlinDependencyVisitor.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.visitor.SourcePathResolver", + "id" : "SourcePathResolver", + "label" : "SourcePathResolver", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/SourcePathResolver.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.visitor.TypeDependencyExtractor", + "id" : "TypeDependencyExtractor", + "label" : "TypeDependencyExtractor", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/TypeDependencyExtractor.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.visitor.UnattributedTypeFqnResolver", + "id" : "UnattributedTypeFqnResolver", + "label" : "UnattributedTypeFqnResolver", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/UnattributedTypeFqnResolver.java", + "markedForRemoval" : false + } ] + } ], + "classes" : [ { + "fqn" : "org.hjug.graphbuilder.CodebaseGraphDTO", + "id" : "CodebaseGraphDTO", + "label" : "CodebaseGraphDTO", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CodebaseGraphDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.CompositeGraphBuilder", + "id" : "CompositeGraphBuilder", + "label" : "CompositeGraphBuilder", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.DependencyCollector", + "id" : "DependencyCollector", + "label" : "DependencyCollector", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/DependencyCollector.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.GraphBuilderConfig", + "id" : "GraphBuilderConfig", + "label" : "GraphBuilderConfig", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/GraphBuilderConfig.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.GraphDependencyCollector", + "id" : "GraphDependencyCollector", + "label" : "GraphDependencyCollector", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/GraphDependencyCollector.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.VertexInfo", + "id" : "VertexInfo", + "label" : "VertexInfo", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/VertexInfo.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.graphbuilder.VertexInfoHydrator", + "id" : "VertexInfoHydrator", + "label" : "VertexInfoHydrator", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/VertexInfoHydrator.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.mavenreport", + "id" : "cluster_5a5b226dc916c25cd94e86c9", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.mavenreport.MavenReportOutputDirectory", + "id" : "MavenReportOutputDirectory", + "label" : "MavenReportOutputDirectory", + "path" : "refactor-first-maven-plugin/src/main/java/org/hjug/mavenreport/MavenReportOutputDirectory.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.mavenreport.RefactorFirstHtmlReport", + "id" : "RefactorFirstHtmlReport", + "label" : "RefactorFirstHtmlReport", + "path" : "refactor-first-maven-plugin/src/main/java/org/hjug/mavenreport/RefactorFirstHtmlReport.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.mavenreport.RefactorFirstMavenCsvReport", + "id" : "RefactorFirstMavenCsvReport", + "label" : "RefactorFirstMavenCsvReport", + "path" : "refactor-first-maven-plugin/src/main/java/org/hjug/mavenreport/RefactorFirstMavenCsvReport.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.mavenreport.RefactorFirstMavenJsonGenerator", + "id" : "RefactorFirstMavenJsonGenerator", + "label" : "RefactorFirstMavenJsonGenerator", + "path" : "refactor-first-maven-plugin/src/main/java/org/hjug/mavenreport/RefactorFirstMavenJsonGenerator.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.mavenreport.RefactorFirstMavenJsonReport", + "id" : "RefactorFirstMavenJsonReport", + "label" : "RefactorFirstMavenJsonReport", + "path" : "refactor-first-maven-plugin/src/main/java/org/hjug/mavenreport/RefactorFirstMavenJsonReport.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.mavenreport.RefactorFirstMavenReport", + "id" : "RefactorFirstMavenReport", + "label" : "RefactorFirstMavenReport", + "path" : "refactor-first-maven-plugin/src/main/java/org/hjug/mavenreport/RefactorFirstMavenReport.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.mavenreport.RefactorFirstSimpleHtmlReport", + "id" : "RefactorFirstSimpleHtmlReport", + "label" : "RefactorFirstSimpleHtmlReport", + "path" : "refactor-first-maven-plugin/src/main/java/org/hjug/mavenreport/RefactorFirstSimpleHtmlReport.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.metrics", + "id" : "cluster_869fe932642cb7510df73c8d", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ { + "name" : "org.hjug.metrics.rules", + "id" : "cluster_d6011c21970de8ae7eafff05", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.metrics.rules.CBORule", + "id" : "CBORule", + "label" : "CBORule", + "path" : "effort-ranker/src/main/java/org/hjug/metrics/rules/CBORule.java", + "markedForRemoval" : false + } ] + } ], + "classes" : [ { + "fqn" : "org.hjug.metrics.CBOClass", + "id" : "CBOClass", + "label" : "CBOClass", + "path" : "effort-ranker/src/main/java/org/hjug/metrics/CBOClass.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.metrics.Disharmony", + "id" : "Disharmony", + "label" : "Disharmony", + "path" : "effort-ranker/src/main/java/org/hjug/metrics/Disharmony.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.metrics.DisharmonyInstance", + "id" : "DisharmonyInstance", + "label" : "DisharmonyInstance", + "path" : "effort-ranker/src/main/java/org/hjug/metrics/DisharmonyInstance.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.metrics.DisharmonyRanker", + "id" : "DisharmonyRanker", + "label" : "DisharmonyRanker", + "path" : "effort-ranker/src/main/java/org/hjug/metrics/DisharmonyRanker.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.metrics.DisharmonyRanker$RankSetter", + "id" : "org_hjug_metrics_DisharmonyRanker_RankSetter", + "label" : "DisharmonyRanker$RankSetter", + "path" : "effort-ranker/src/main/java/org/hjug/metrics/DisharmonyRanker.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.metrics.DisharmonyRanker$ValueExtractor", + "id" : "org_hjug_metrics_DisharmonyRanker_ValueExtractor", + "label" : "DisharmonyRanker$ValueExtractor", + "path" : "effort-ranker/src/main/java/org/hjug/metrics/DisharmonyRanker.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.metrics.GodClass", + "id" : "GodClass", + "label" : "GodClass", + "path" : "effort-ranker/src/main/java/org/hjug/metrics/GodClass.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.metrics.GodClassRanker", + "id" : "GodClassRanker", + "label" : "GodClassRanker", + "path" : "effort-ranker/src/main/java/org/hjug/metrics/GodClassRanker.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.refactorfirst", + "id" : "cluster_622c04a26e1ba36b6ebca283", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ { + "name" : "org.hjug.refactorfirst.report", + "id" : "cluster_864d6940ac14438961598d5a", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ { + "name" : "org.hjug.refactorfirst.report.json", + "id" : "cluster_bb20afe0ec6010144ae2060c", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.refactorfirst.report.json.JsonReport", + "id" : "JsonReport", + "label" : "JsonReport", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/json/JsonReport.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.json.JsonReportDisharmonyEntry", + "id" : "JsonReportDisharmonyEntry", + "label" : "JsonReportDisharmonyEntry", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/json/JsonReportDisharmonyEntry.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.json.JsonReportExecutor", + "id" : "JsonReportExecutor", + "label" : "JsonReportExecutor", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/json/JsonReportExecutor.java", + "markedForRemoval" : false + } ] + }, { + "name" : "org.hjug.refactorfirst.report.model", + "id" : "cluster_8b5bd27cd192f3c043f79d74", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.refactorfirst.report.model.ChartJsBubbleDTO", + "id" : "ChartJsBubbleDTO", + "label" : "ChartJsBubbleDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/ChartJsBubbleDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.ClassCyclesDTO", + "id" : "ClassCyclesDTO", + "label" : "ClassCyclesDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/ClassCyclesDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.ClassNodeDTO", + "id" : "ClassNodeDTO", + "label" : "ClassNodeDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/ClassNodeDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.ClassRelationshipDTO", + "id" : "ClassRelationshipDTO", + "label" : "ClassRelationshipDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/ClassRelationshipDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.ClassRelationshipsToRemoveDTO", + "id" : "ClassRelationshipsToRemoveDTO", + "label" : "ClassRelationshipsToRemoveDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/ClassRelationshipsToRemoveDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.CycleBreakdownRowDTO", + "id" : "CycleBreakdownRowDTO", + "label" : "CycleBreakdownRowDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/CycleBreakdownRowDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.CycleSummaryDTO", + "id" : "CycleSummaryDTO", + "label" : "CycleSummaryDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/CycleSummaryDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.DisharmonyChartDTO", + "id" : "DisharmonyChartDTO", + "label" : "DisharmonyChartDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/DisharmonyChartDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.DisharmonySectionDTO", + "id" : "DisharmonySectionDTO", + "label" : "DisharmonySectionDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/DisharmonySectionDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.DisharmonyTableCellDTO", + "id" : "DisharmonyTableCellDTO", + "label" : "DisharmonyTableCellDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/DisharmonyTableCellDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.DisharmonyTableDTO", + "id" : "DisharmonyTableDTO", + "label" : "DisharmonyTableDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/DisharmonyTableDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.DisharmonyTableRowDTO", + "id" : "DisharmonyTableRowDTO", + "label" : "DisharmonyTableRowDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/DisharmonyTableRowDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.EdgeDTO", + "id" : "EdgeDTO", + "label" : "EdgeDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/EdgeDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.GraphVisualDTO", + "id" : "GraphVisualDTO", + "label" : "GraphVisualDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/GraphVisualDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.HierarchyDTO", + "id" : "HierarchyDTO", + "label" : "HierarchyDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/HierarchyDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.LargestCycleDTO", + "id" : "LargestCycleDTO", + "label" : "LargestCycleDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/LargestCycleDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.PackageNodeDTO", + "id" : "PackageNodeDTO", + "label" : "PackageNodeDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/PackageNodeDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.PackageRelationshipDTO", + "id" : "PackageRelationshipDTO", + "label" : "PackageRelationshipDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/PackageRelationshipDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.PackageRelationshipsToRemoveDTO", + "id" : "PackageRelationshipsToRemoveDTO", + "label" : "PackageRelationshipsToRemoveDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/PackageRelationshipsToRemoveDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.ProjectMetadataDTO", + "id" : "ProjectMetadataDTO", + "label" : "ProjectMetadataDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/ProjectMetadataDTO.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.model.RefactorFirstReportDTO", + "id" : "RefactorFirstReportDTO", + "label" : "RefactorFirstReportDTO", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/RefactorFirstReportDTO.java", + "markedForRemoval" : false + } ] + } ], + "classes" : [ { + "fqn" : "org.hjug.refactorfirst.report.CsvReport", + "id" : "CsvReport", + "label" : "CsvReport", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/CsvReport.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.HierarchyBuilder", + "id" : "HierarchyBuilder", + "label" : "HierarchyBuilder", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/HierarchyBuilder.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.HierarchyBuilder$Pkg", + "id" : "org_hjug_refactorfirst_report_HierarchyBuilder_Pkg", + "label" : "HierarchyBuilder$Pkg", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/HierarchyBuilder.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.HtmlReport", + "id" : "HtmlReport", + "label" : "HtmlReport", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java", + "markedForRemoval" : true + }, { + "fqn" : "org.hjug.refactorfirst.report.JsonGenerator", + "id" : "JsonGenerator", + "label" : "JsonGenerator", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.NestedDotBuilder", + "id" : "NestedDotBuilder", + "label" : "NestedDotBuilder", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/NestedDotBuilder.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.ReportWriter", + "id" : "ReportWriter", + "label" : "ReportWriter", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", + "markedForRemoval" : true + }, { + "fqn" : "org.hjug.refactorfirst.report.ReportWriter$FallbackDirectoryOps", + "id" : "org_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps", + "label" : "ReportWriter$FallbackDirectoryOps", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.ReportWriter$ReportWriteException", + "id" : "org_hjug_refactorfirst_report_ReportWriter_ReportWriteException", + "label" : "ReportWriter$ReportWriteException", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.ReportWriter$SecureDirectoryOps", + "id" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps", + "label" : "ReportWriter$SecureDirectoryOps", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.ReportWriter$SecureDirectoryOpsImpl", + "id" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl", + "label" : "ReportWriter$SecureDirectoryOpsImpl", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.SimpleHtmlReport", + "id" : "SimpleHtmlReport", + "label" : "SimpleHtmlReport", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.SimpleHtmlReport$DisharmonySpec", + "id" : "org_hjug_refactorfirst_report_SimpleHtmlReport_DisharmonySpec", + "label" : "SimpleHtmlReport$DisharmonySpec", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java", + "markedForRemoval" : false + } ] + } ], + "classes" : [ { + "fqn" : "org.hjug.refactorfirst.Main", + "id" : "Main", + "label" : "Main", + "path" : "cli/src/main/java/org/hjug/refactorfirst/Main.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.ReportCommand", + "id" : "ReportCommand", + "label" : "ReportCommand", + "path" : "cli/src/main/java/org/hjug/refactorfirst/ReportCommand.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.ReportType", + "id" : "ReportType", + "label" : "ReportType", + "path" : "cli/src/main/java/org/hjug/refactorfirst/ReportType.java", + "markedForRemoval" : false + } ] + } ], + "classes" : [ ] + } ], + "edges" : [ { + "source" : "AbstractDependencyVisitor", + "target" : "BaseTypeProcessor", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "AbstractDependencyVisitor", + "target" : "DependencyCollector", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "AbstractDependencyVisitor", + "target" : "DependencyVisitorLogic", + "weight" : 14, + "markedForRemoval" : false + }, { + "source" : "AbstractDependencyVisitor", + "target" : "DependencyVisitorState", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "AbstractDependencyVisitor", + "target" : "SourcePathResolver", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "AbstractDependencyVisitor", + "target" : "org_hjug_graphbuilder_visitor_AbstractDependencyVisitor_1", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "BaseTypeProcessor", + "target" : "DependencyCollector", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "BaseTypeProcessor", + "target" : "TypeDependencyExtractor", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "CBOClass", + "target" : "Disharmony", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "ChangePronenessRanker", + "target" : "GitLogReader", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "ChangePronenessRanker", + "target" : "ScmLogInfo", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "ClassCyclesDTO", + "target" : "CycleSummaryDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "ClassCyclesDTO", + "target" : "LargestCycleDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "ClassMetrics", + "target" : "MethodMetrics", + "weight" : 13, + "markedForRemoval" : false + }, { + "source" : "ClassRelationshipsToRemoveDTO", + "target" : "ClassRelationshipDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "CodebaseGraphDTO", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "CodebaseGraphDTO", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "CompositeGraphBuilder", + "target" : "CodebaseGraphDTO", + "weight" : 11, + "markedForRemoval" : false + }, { + "source" : "CompositeGraphBuilder", + "target" : "GraphBuilderConfig", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "CompositeGraphBuilder", + "target" : "JavaSourceFileGraphBuilder", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "CompositeGraphBuilder", + "target" : "KotlinSourceFileGraphBuilder", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "CompositeGraphBuilder", + "target" : "VertexInfo", + "weight" : 35, + "markedForRemoval" : false + }, { + "source" : "CompositeGraphBuilder", + "target" : "VertexInfoHydrator", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "CompositeGraphBuilder", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "CompositeGraphBuilder", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "Console", + "target" : "io_confluent_ksql_cli_console_Console_CliCmdExecutor", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "Console", + "target" : "io_confluent_ksql_cli_console_Console_NoOpRowCaptor", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "Console", + "target" : "io_confluent_ksql_cli_console_Console_RowCaptor", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "CBOClass", + "weight" : 7, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "CBORule", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "ChangePronenessRanker", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "CodebaseGraphDTO", + "weight" : 10, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "Disharmony", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "DisharmonyInstance", + "weight" : 11, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "DisharmonyRanker", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "GitLogReader", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "GodClass", + "weight" : 12, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "GodClassRanker", + "weight" : 6, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "RankedDisharmony", + "weight" : 24, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "ScmLogInfo", + "weight" : 16, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "VertexInfo", + "weight" : 19, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "CostBenefitCalculator", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "CsvReport", + "target" : "CostBenefitCalculator", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "CsvReport", + "target" : "GitLogReader", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "CsvReport", + "target" : "RankedDisharmony", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "CsvReport", + "target" : "ReportWriter", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "CsvReportTask", + "target" : "CsvReport", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "CsvReportTask", + "target" : "RefactorFirstExtension", + "weight" : 8, + "markedForRemoval" : false + }, { + "source" : "CsvReportTask", + "target" : "RefactorFirstPlugin", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "CycleNode", + "target" : "Disharmony", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "CycleNode", + "target" : "ScmLogInfo", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "CycleRanker", + "target" : "CircularReferenceChecker", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "CycleRanker", + "target" : "CodebaseGraphDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "CycleRanker", + "target" : "CompositeGraphBuilder", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "CycleRanker", + "target" : "CycleNode", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "CycleRanker", + "target" : "GraphBuilderConfig", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "CycleRanker", + "target" : "RankedCycle", + "weight" : 8, + "markedForRemoval" : false + }, { + "source" : "CycleRanker", + "target" : "VertexInfo", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "CycleRemovalComputer", + "target" : "CircularReferenceChecker", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "CycleRemovalComputer", + "target" : "CycleRemovalResult", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "CycleRemovalComputer", + "target" : "DirectedFeedbackVertexSetResult", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "CycleRemovalComputer", + "target" : "DirectedFeedbackVertexSetSolver", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "CycleRemovalComputer", + "target" : "EnhancedParameterComputer", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "CycleRemovalComputer", + "target" : "PageRankFAS", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "CycleRemovalComputer", + "target" : "org_hjug_feedback_vertex_kernelized_EnhancedParameterComputer_EnhancedParameters", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "DependencyVisitorLogic", + "target" : "DependencyVisitorState", + "weight" : 14, + "markedForRemoval" : false + }, { + "source" : "DependencyVisitorLogic", + "target" : "SourcePathResolver", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "DependencyVisitorLogic", + "target" : "UnattributedTypeFqnResolver", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "DependencyVisitorLogic", + "target" : "org_hjug_graphbuilder_visitor_DependencyVisitorLogic_ClassSnapshot", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "DependencyVisitorState", + "target" : "BaseTypeProcessor", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "DirectedFeedbackVertexSetSolver", + "target" : "DirectedFeedbackVertexSetResult", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "DirectedFeedbackVertexSetSolver", + "target" : "SuperTypeToken", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "DirectedFeedbackVertexSetSolver", + "target" : "org_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathComputationStats", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "DirectedFeedbackVertexSetSolver", + "target" : "org_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathContext", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "DisharmonyChartDTO", + "target" : "ChartJsBubbleDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "DisharmonyDetector", + "target" : "ClassMetrics", + "weight" : 99, + "markedForRemoval" : false + }, { + "source" : "DisharmonyDetector", + "target" : "DisharmonyMetric", + "weight" : 44, + "markedForRemoval" : false + }, { + "source" : "DisharmonyDetector", + "target" : "MethodMetrics", + "weight" : 40, + "markedForRemoval" : false + }, { + "source" : "DisharmonyDetector", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony", + "weight" : 30, + "markedForRemoval" : false + }, { + "source" : "DisharmonyDetector", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_Clone", + "weight" : 20, + "markedForRemoval" : false + }, { + "source" : "DisharmonyDetector", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_FlaggedClassData", + "weight" : 10, + "markedForRemoval" : false + }, { + "source" : "DisharmonyDetector", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony", + "weight" : 15, + "markedForRemoval" : false + }, { + "source" : "DisharmonyDetector", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "DisharmonyInstance", + "target" : "Disharmony", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "DisharmonyInstance", + "target" : "DisharmonyMetric", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "DisharmonyMetric", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyMetric_Direction", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "DisharmonyRanker", + "target" : "DisharmonyInstance", + "weight" : 7, + "markedForRemoval" : false + }, { + "source" : "DisharmonyRanker", + "target" : "DisharmonyMetric", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "DisharmonyRanker", + "target" : "org_hjug_metrics_DisharmonyRanker_RankSetter", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "DisharmonyRanker", + "target" : "org_hjug_metrics_DisharmonyRanker_ValueExtractor", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "DisharmonySectionDTO", + "target" : "DisharmonyChartDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "DisharmonySectionDTO", + "target" : "DisharmonyTableDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "DisharmonyTableDTO", + "target" : "DisharmonyTableRowDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "DisharmonyTableRowDTO", + "target" : "DisharmonyTableCellDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "EdgeInfoCalculator", + "target" : "EdgeInfo", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "EdgeRemovalCalculator", + "target" : "CircularReferenceChecker", + "weight" : 6, + "markedForRemoval" : false + }, { + "source" : "EdgeRemovalCalculator", + "target" : "DSM", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "EdgeRemovalCalculator", + "target" : "EdgeToRemoveInfo", + "weight" : 7, + "markedForRemoval" : false + }, { + "source" : "EnhancedParameterComputer", + "target" : "FeedbackVertexSetComputer", + "weight" : 6, + "markedForRemoval" : false + }, { + "source" : "EnhancedParameterComputer", + "target" : "ModulatorComputer", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "EnhancedParameterComputer", + "target" : "SuperTypeToken", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "EnhancedParameterComputer", + "target" : "TreewidthComputer", + "weight" : 6, + "markedForRemoval" : false + }, { + "source" : "EnhancedParameterComputer", + "target" : "org_hjug_feedback_vertex_kernelized_EnhancedParameterComputer_EnhancedParameters", + "weight" : 14, + "markedForRemoval" : false + }, { + "source" : "EnhancedParameterComputer", + "target" : "org_hjug_feedback_vertex_kernelized_ModulatorComputer_ModulatorResult", + "weight" : 6, + "markedForRemoval" : false + }, { + "source" : "FeedbackArcSetSolver", + "target" : "org_hjug_feedback_arc_approximate_FeedbackArcSetResult", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "FeedbackVertexSetComputer", + "target" : "SuperTypeToken", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "FeedbackVertexSetSolver", + "target" : "FeedbackVertexSetResult", + "weight" : 16, + "markedForRemoval" : false + }, { + "source" : "FeedbackVertexSetSolver", + "target" : "org_hjug_feedback_vertex_approximate_FeedbackVertexSetSolver_CutCandidate", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "GitLogReader", + "target" : "ScmLogInfo", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "GitLogReader", + "target" : "org_hjug_git_GitLogReader_CommitWalkStats", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "GodClass", + "target" : "Disharmony", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "GodClassRanker", + "target" : "GodClass", + "weight" : 18, + "markedForRemoval" : false + }, { + "source" : "GraphDataGenerator", + "target" : "RankedDisharmony", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "GraphDependencyCollector", + "target" : "DependencyCollector", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "GraphDependencyCollector", + "target" : "VertexInfo", + "weight" : 8, + "markedForRemoval" : false + }, { + "source" : "GraphMetricsCollector", + "target" : "ClassMetrics", + "weight" : 33, + "markedForRemoval" : false + }, { + "source" : "GraphMetricsCollector", + "target" : "DependencyCollector", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "GraphMetricsCollector", + "target" : "MethodMetrics", + "weight" : 10, + "markedForRemoval" : false + }, { + "source" : "GraphMetricsCollector", + "target" : "VertexInfo", + "weight" : 15, + "markedForRemoval" : false + }, { + "source" : "GraphVisualDTO", + "target" : "HierarchyDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "HierarchyBuilder", + "target" : "ClassNodeDTO", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "HierarchyBuilder", + "target" : "CodebaseGraphDTO", + "weight" : 6, + "markedForRemoval" : false + }, { + "source" : "HierarchyBuilder", + "target" : "EdgeDTO", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "HierarchyBuilder", + "target" : "HierarchyDTO", + "weight" : 6, + "markedForRemoval" : false + }, { + "source" : "HierarchyBuilder", + "target" : "HtmlReport", + "weight" : 7, + "markedForRemoval" : true + }, { + "source" : "HierarchyBuilder", + "target" : "PackageNodeDTO", + "weight" : 8, + "markedForRemoval" : false + }, { + "source" : "HierarchyBuilder", + "target" : "RankedCycle", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "HierarchyBuilder", + "target" : "SimpleHtmlReport", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "HierarchyBuilder", + "target" : "VertexInfo", + "weight" : 18, + "markedForRemoval" : false + }, { + "source" : "HierarchyBuilder", + "target" : "org_hjug_refactorfirst_report_HierarchyBuilder_Pkg", + "weight" : 23, + "markedForRemoval" : false + }, { + "source" : "HierarchyDTO", + "target" : "EdgeDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "HierarchyDTO", + "target" : "PackageNodeDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "HtmlReport", + "target" : "CodebaseGraphDTO", + "weight" : 13, + "markedForRemoval" : false + }, { + "source" : "HtmlReport", + "target" : "GraphDataGenerator", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "HtmlReport", + "target" : "HierarchyBuilder", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "HtmlReport", + "target" : "HierarchyDTO", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "HtmlReport", + "target" : "NestedDotBuilder", + "weight" : 3, + "markedForRemoval" : true + }, { + "source" : "HtmlReport", + "target" : "RankedCycle", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "HtmlReport", + "target" : "RankedDisharmony", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "HtmlReport", + "target" : "SimpleHtmlReport", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "HtmlReport", + "target" : "VertexInfo", + "weight" : 11, + "markedForRemoval" : false + }, { + "source" : "HtmlReportTask", + "target" : "HtmlReport", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "HtmlReportTask", + "target" : "RefactorFirstExtension", + "weight" : 13, + "markedForRemoval" : false + }, { + "source" : "HtmlReportTask", + "target" : "RefactorFirstPlugin", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "HtmlReportTask", + "target" : "SimpleHtmlReport", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "AbstractDependencyVisitor", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "ClassMetrics", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "CodebaseGraphDTO", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "DisharmonyDetector", + "weight" : 18, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "GraphBuilderConfig", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "GraphDependencyCollector", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "GraphMetricsCollector", + "weight" : 6, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "Java25ParserFactory", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "JavaVisitor", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "MetricsCollectingVisitor", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "SourceFileGraphBuilder", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "VertexInfo", + "weight" : 14, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "VertexInfoHydrator", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "JavaSourceFileGraphBuilder", + "target" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "JavaVisitor", + "target" : "AbstractDependencyVisitor", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JavaVisitor", + "target" : "DependencyCollector", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "ChartJsBubbleDTO", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "ClassCyclesDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "ClassRelationshipDTO", + "weight" : 6, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "ClassRelationshipsToRemoveDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "CodebaseGraphDTO", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "CostBenefitCalculator", + "weight" : 7, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "CycleBreakdownRowDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "CycleRanker", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "CycleRemovalComputer", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "CycleRemovalResult", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "CycleSummaryDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "DisharmonyChartDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "DisharmonyInstance", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "DisharmonyMetric", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "DisharmonySectionDTO", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "DisharmonyTableCellDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "DisharmonyTableDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "DisharmonyTableRowDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "GitLogReader", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "GraphVisualDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "HierarchyBuilder", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "HierarchyDTO", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "HtmlReport", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "LargestCycleDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "PackageRelationshipDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "PackageRelationshipsToRemoveDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "ProjectMetadataDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "RankedCycle", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "RankedDisharmony", + "weight" : 10, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "RefactorFirstReportDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "SimpleHtmlReport", + "weight" : 22, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "VertexInfo", + "weight" : 8, + "markedForRemoval" : false + }, { + "source" : "JsonGenerator", + "target" : "org_hjug_refactorfirst_report_SimpleHtmlReport_DisharmonySpec", + "weight" : 17, + "markedForRemoval" : false + }, { + "source" : "JsonReport", + "target" : "JsonReportDisharmonyEntry", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JsonReportDisharmonyEntry", + "target" : "RankedDisharmony", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "JsonReportExecutor", + "target" : "CostBenefitCalculator", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "JsonReportExecutor", + "target" : "JsonReport", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "JsonReportExecutor", + "target" : "JsonReportDisharmonyEntry", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JsonReportExecutor", + "target" : "RankedDisharmony", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JsonReportExecutor", + "target" : "ReportWriter", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "JsonReportTask", + "target" : "JsonReportExecutor", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "JsonReportTask", + "target" : "RefactorFirstExtension", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "JsonReportTask", + "target" : "RefactorFirstPlugin", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "KotlinDependencyVisitor", + "target" : "BaseTypeProcessor", + "weight" : 8, + "markedForRemoval" : false + }, { + "source" : "KotlinDependencyVisitor", + "target" : "DependencyCollector", + "weight" : 7, + "markedForRemoval" : false + }, { + "source" : "KotlinDependencyVisitor", + "target" : "DependencyVisitorLogic", + "weight" : 17, + "markedForRemoval" : false + }, { + "source" : "KotlinDependencyVisitor", + "target" : "DependencyVisitorState", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "KotlinDependencyVisitor", + "target" : "SourcePathResolver", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "KotlinDependencyVisitor", + "target" : "org_hjug_graphbuilder_visitor_KotlinDependencyVisitor_1", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "KotlinMetricsCollectingVisitor", + "target" : "ClassMetrics", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "KotlinMetricsCollectingVisitor", + "target" : "GraphMetricsCollector", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "KotlinMetricsCollectingVisitor", + "target" : "MetricsVisitorLogic", + "weight" : 17, + "markedForRemoval" : false + }, { + "source" : "KotlinMetricsCollectingVisitor", + "target" : "MetricsVisitorState", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "KotlinMetricsCollectingVisitor", + "target" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "KotlinMetricsCollectingVisitor", + "target" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "KotlinMetricsCollectingVisitor", + "target" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_OverridePredicate", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "KotlinSourceFileGraphBuilder", + "target" : "CodebaseGraphDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "KotlinSourceFileGraphBuilder", + "target" : "GraphBuilderConfig", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "KotlinSourceFileGraphBuilder", + "target" : "GraphDependencyCollector", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "KotlinSourceFileGraphBuilder", + "target" : "GraphMetricsCollector", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "KotlinSourceFileGraphBuilder", + "target" : "JavaSourceFileGraphBuilder", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "KotlinSourceFileGraphBuilder", + "target" : "KotlinDependencyVisitor", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "KotlinSourceFileGraphBuilder", + "target" : "KotlinMetricsCollectingVisitor", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "KotlinSourceFileGraphBuilder", + "target" : "SourceFileGraphBuilder", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "KotlinSourceFileGraphBuilder", + "target" : "VertexInfo", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "LargestCycleDTO", + "target" : "CycleBreakdownRowDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "LargestCycleDTO", + "target" : "HierarchyDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "LineDigraph", + "target" : "LineVertex", + "weight" : 68, + "markedForRemoval" : false + }, { + "source" : "Main", + "target" : "ReportCommand", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "MavenReportOutputDirectory", + "target" : "ReportWriter", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "MetricsCollectingVisitor", + "target" : "GraphMetricsCollector", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "MetricsCollectingVisitor", + "target" : "MetricsVisitorLogic", + "weight" : 10, + "markedForRemoval" : false + }, { + "source" : "MetricsCollectingVisitor", + "target" : "MetricsVisitorState", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "MetricsCollectingVisitor", + "target" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "MetricsCollectingVisitor", + "target" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "MetricsCollectingVisitor", + "target" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_OverridePredicate", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "MetricsVisitorLogic", + "target" : "ClassMetrics", + "weight" : 28, + "markedForRemoval" : false + }, { + "source" : "MetricsVisitorLogic", + "target" : "ComplexityCalculator", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "MetricsVisitorLogic", + "target" : "GraphMetricsCollector", + "weight" : 13, + "markedForRemoval" : false + }, { + "source" : "MetricsVisitorLogic", + "target" : "MethodMetrics", + "weight" : 31, + "markedForRemoval" : false + }, { + "source" : "MetricsVisitorLogic", + "target" : "MetricsVisitorState", + "weight" : 12, + "markedForRemoval" : false + }, { + "source" : "MetricsVisitorLogic", + "target" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "MetricsVisitorLogic", + "target" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "MetricsVisitorLogic", + "target" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_OverridePredicate", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "MetricsVisitorState", + "target" : "ClassMetrics", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "MetricsVisitorState", + "target" : "MethodMetrics", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "MinimumFeedbackArcSetSolver", + "target" : "SuperTypeToken", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "MinimumFeedbackArcSetSolver", + "target" : "org_hjug_feedback_arc_exact_FeedbackArcSetResult", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "ModulatorComputer", + "target" : "FeedbackVertexSetComputer", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "ModulatorComputer", + "target" : "SuperTypeToken", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "ModulatorComputer", + "target" : "TreewidthComputer", + "weight" : 14, + "markedForRemoval" : false + }, { + "source" : "ModulatorComputer", + "target" : "org_hjug_feedback_vertex_kernelized_ModulatorComputer_ModulatorResult", + "weight" : 9, + "markedForRemoval" : false + }, { + "source" : "NestedDotBuilder", + "target" : "ClassNodeDTO", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "NestedDotBuilder", + "target" : "EdgeDTO", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "NestedDotBuilder", + "target" : "HierarchyDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "NestedDotBuilder", + "target" : "HtmlReport", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "NestedDotBuilder", + "target" : "PackageNodeDTO", + "weight" : 7, + "markedForRemoval" : false + }, { + "source" : "PackageNodeDTO", + "target" : "ClassNodeDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "PackageRelationshipDTO", + "target" : "ClassRelationshipDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "PackageRelationshipsToRemoveDTO", + "target" : "PackageRelationshipDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "PageRankFAS", + "target" : "LineDigraph", + "weight" : 12, + "markedForRemoval" : false + }, { + "source" : "PageRankFAS", + "target" : "LineVertex", + "weight" : 40, + "markedForRemoval" : false + }, { + "source" : "PageRankFAS", + "target" : "SuperTypeToken", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "ParameterComputer", + "target" : "FeedbackVertexSetComputer", + "weight" : 6, + "markedForRemoval" : false + }, { + "source" : "ParameterComputer", + "target" : "SuperTypeToken", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "ParameterComputer", + "target" : "TreewidthComputer", + "weight" : 7, + "markedForRemoval" : false + }, { + "source" : "ParameterComputer", + "target" : "org_hjug_feedback_vertex_kernelized_ParameterComputer_Parameters", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "RankedCycle", + "target" : "CycleNode", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "RankedDisharmony", + "target" : "CBOClass", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RankedDisharmony", + "target" : "DisharmonyInstance", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RankedDisharmony", + "target" : "DisharmonyMetric", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RankedDisharmony", + "target" : "GodClass", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RankedDisharmony", + "target" : "ScmLogInfo", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstHtmlReport", + "target" : "HtmlReport", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstHtmlReport", + "target" : "MavenReportOutputDirectory", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstHtmlReport", + "target" : "SimpleHtmlReport", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstMavenCsvReport", + "target" : "CsvReport", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstMavenCsvReport", + "target" : "MavenReportOutputDirectory", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstMavenJsonGenerator", + "target" : "JsonGenerator", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstMavenJsonReport", + "target" : "JsonReportExecutor", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstMavenJsonReport", + "target" : "MavenReportOutputDirectory", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstMavenReport", + "target" : "HtmlReport", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstMavenReport", + "target" : "SimpleHtmlReport", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstReportDTO", + "target" : "ClassCyclesDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstReportDTO", + "target" : "ClassRelationshipsToRemoveDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstReportDTO", + "target" : "DisharmonySectionDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstReportDTO", + "target" : "GraphVisualDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstReportDTO", + "target" : "PackageRelationshipsToRemoveDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstReportDTO", + "target" : "ProjectMetadataDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstSimpleHtmlReport", + "target" : "MavenReportOutputDirectory", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "RefactorFirstSimpleHtmlReport", + "target" : "SimpleHtmlReport", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "ReportCommand", + "target" : "CsvReport", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "ReportCommand", + "target" : "HtmlReport", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "ReportCommand", + "target" : "JsonReportExecutor", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "ReportCommand", + "target" : "ReportType", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "ReportCommand", + "target" : "ReportWriter", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "ReportCommand", + "target" : "SimpleHtmlReport", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "ReportWriter", + "target" : "org_hjug_refactorfirst_report_ReportWriter_ReportWriteException", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "ReportWriter", + "target" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReport", + "target" : "CodebaseGraphDTO", + "weight" : 13, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReport", + "target" : "CostBenefitCalculator", + "weight" : 7, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReport", + "target" : "CycleRanker", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReport", + "target" : "CycleRemovalComputer", + "weight" : 4, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReport", + "target" : "CycleRemovalResult", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReport", + "target" : "DisharmonyInstance", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReport", + "target" : "DisharmonyMetric", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReport", + "target" : "GitLogReader", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReport", + "target" : "RankedCycle", + "weight" : 10, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReport", + "target" : "RankedDisharmony", + "weight" : 16, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReport", + "target" : "ReportWriter", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReport", + "target" : "VertexInfo", + "weight" : 11, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReport", + "target" : "org_hjug_refactorfirst_report_SimpleHtmlReport_DisharmonySpec", + "weight" : 34, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReportTask", + "target" : "RefactorFirstExtension", + "weight" : 13, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReportTask", + "target" : "RefactorFirstPlugin", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "SimpleHtmlReportTask", + "target" : "SimpleHtmlReport", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "SourceFileGraphBuilder", + "target" : "CodebaseGraphDTO", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "SourceFileGraphBuilder", + "target" : "GraphBuilderConfig", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "SparseIntDWGEdgeRemovalCalculator", + "target" : "EdgeToRemoveInfo", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "VertexInfoHydrator", + "target" : "VertexInfo", + "weight" : 6, + "markedForRemoval" : false + }, { + "source" : "io_confluent_ksql_cli_console_Console_NoOpRowCaptor", + "target" : "io_confluent_ksql_cli_console_Console_RowCaptor", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony", + "target" : "ClassMetrics", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony", + "target" : "DisharmonyMetric", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony", + "target" : "DisharmonyMetric", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony", + "target" : "MethodMetrics", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry", + "target" : "ClassMetrics", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry", + "target" : "MethodMetrics", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot", + "target" : "ClassMetrics", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot", + "target" : "MethodMetrics", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "org_hjug_graphbuilder_visitor_AbstractDependencyVisitor_1", + "target" : "DependencyCollector", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "org_hjug_graphbuilder_visitor_KotlinDependencyVisitor_1", + "target" : "DependencyCollector", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "org_hjug_refactorfirst_report_HierarchyBuilder_Pkg", + "target" : "ClassNodeDTO", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "org_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps", + "target" : "ReportWriter", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "org_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps", + "target" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps", + "target" : "org_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps", + "weight" : 1, + "markedForRemoval" : true + }, { + "source" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps", + "target" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl", + "weight" : 1, + "markedForRemoval" : true + }, { + "source" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl", + "target" : "ReportWriter", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl", + "target" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps", + "weight" : 1, + "markedForRemoval" : false + } ] + }, "hasEdges" : false }, "classRelationshipsToRemove" : { - "cycleCount" : 1, - "relationshipsToRemoveCount" : 2, + "cycleCount" : 2, + "relationshipsToRemoveCount" : 4, "hasRelationships" : true, "relationships" : [ { "sourceClass" : "org.hjug.refactorfirst.report.ReportWriter$SecureDirectoryOps", @@ -51,6 +2888,36 @@ "effortRank" : 1, "alsoRemovesPackageRelationship" : false, "packageCycleCount" : 0 + }, { + "sourceClass" : "org.hjug.refactorfirst.report.HtmlReport", + "targetClass" : "org.hjug.refactorfirst.report.NestedDotBuilder", + "sourceClassPath" : "report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java", + "targetClassPath" : "report/src/main/java/org/hjug/refactorfirst/report/NestedDotBuilder.java", + "simpleSourceClassName" : "HtmlReport", + "simpleTargetClassName" : "NestedDotBuilder", + "sourceMarked" : true, + "targetMarked" : false, + "weight" : 3, + "priority" : 3, + "cycleCount" : 1, + "effortRank" : 3, + "alsoRemovesPackageRelationship" : false, + "packageCycleCount" : 0 + }, { + "sourceClass" : "org.hjug.refactorfirst.report.HierarchyBuilder", + "targetClass" : "org.hjug.refactorfirst.report.HtmlReport", + "sourceClassPath" : "report/src/main/java/org/hjug/refactorfirst/report/HierarchyBuilder.java", + "targetClassPath" : "report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java", + "simpleSourceClassName" : "HierarchyBuilder", + "simpleTargetClassName" : "HtmlReport", + "sourceMarked" : false, + "targetMarked" : true, + "weight" : 7, + "priority" : 4, + "cycleCount" : 1, + "effortRank" : 7, + "alsoRemovesPackageRelationship" : false, + "packageCycleCount" : 0 } ] }, "packageMap" : { @@ -59,7 +2926,393 @@ "relationshipCount" : 37, "dotThreshold" : 4000, "dotThresholdExceeded" : false, - "dot" : "strict digraph G {\npackage_622c04a26e1ba36b6ebca283 -> package_864d6940ac14438961598d5a [ label = \"10\" weight = \"10\" ];\npackage_622c04a26e1ba36b6ebca283 -> package_bb20afe0ec6010144ae2060c [ label = \"3\" weight = \"3\" ];\npackage_275b39592e996f9bc7d2bab4 -> package_179967d6e66ef95e5ec582dc [ label = \"12\" weight = \"12\" ];\npackage_275b39592e996f9bc7d2bab4 -> package_98c578ab6c4dd833f53d3aee [ label = \"6\" weight = \"6\" color = \"red\" ];\npackage_98c578ab6c4dd833f53d3aee -> package_275b39592e996f9bc7d2bab4 [ label = \"10\" weight = \"10\" ];\npackage_98c578ab6c4dd833f53d3aee -> package_d36e09db80f0e2bbc4ffd5c7 [ label = \"4\" weight = \"4\" ];\npackage_98c578ab6c4dd833f53d3aee -> package_179967d6e66ef95e5ec582dc [ label = \"37\" weight = \"37\" ];\npackage_179967d6e66ef95e5ec582dc -> package_275b39592e996f9bc7d2bab4 [ label = \"1\" weight = \"1\" color = \"red\" ];\npackage_d36e09db80f0e2bbc4ffd5c7 -> package_275b39592e996f9bc7d2bab4 [ label = \"14\" weight = \"14\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_cc2439ece2ff219a79eb369d [ label = \"27\" weight = \"27\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_d6011c21970de8ae7eafff05 [ label = \"1\" weight = \"1\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_869fe932642cb7510df73c8d [ label = \"46\" weight = \"46\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_275b39592e996f9bc7d2bab4 [ label = \"16\" weight = \"16\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_179967d6e66ef95e5ec582dc [ label = \"7\" weight = \"7\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_6da3c08ea2d561edab77673f [ label = \"2\" weight = \"2\" ];\npackage_869fe932642cb7510df73c8d -> package_179967d6e66ef95e5ec582dc [ label = \"2\" weight = \"2\" ];\npackage_5770287cc40afd5bd6812d59 -> package_0b6cea3e7e0dde98e8d142c3 [ label = \"2\" weight = \"2\" ];\npackage_d30a7a8d892c5e6113a07e84 -> package_0b6cea3e7e0dde98e8d142c3 [ label = \"3\" weight = \"3\" ];\npackage_0b6cea3e7e0dde98e8d142c3 -> package_6da3c08ea2d561edab77673f [ label = \"2\" weight = \"2\" ];\npackage_0b6cea3e7e0dde98e8d142c3 -> package_d2f1dd27b2e43b88238a4c05 [ label = \"10\" weight = \"10\" color = \"red\" ];\npackage_0b6cea3e7e0dde98e8d142c3 -> package_d30a7a8d892c5e6113a07e84 [ label = \"2\" weight = \"2\" color = \"red\" ];\npackage_d2f1dd27b2e43b88238a4c05 -> package_0b6cea3e7e0dde98e8d142c3 [ label = \"12\" weight = \"12\" ];\npackage_e16f87ed4cbaa8972b66b80b -> package_bfb0d6f0cb59390b479b08a1 [ label = \"2\" weight = \"2\" ];\npackage_c28460328a6700365ccc109d -> package_864d6940ac14438961598d5a [ label = \"9\" weight = \"9\" ];\npackage_c28460328a6700365ccc109d -> package_bb20afe0ec6010144ae2060c [ label = \"3\" weight = \"3\" ];\npackage_5a5b226dc916c25cd94e86c9 -> package_864d6940ac14438961598d5a [ label = \"16\" weight = \"16\" ];\npackage_5a5b226dc916c25cd94e86c9 -> package_bb20afe0ec6010144ae2060c [ label = \"3\" weight = \"3\" ];\npackage_864d6940ac14438961598d5a -> package_cc2439ece2ff219a79eb369d [ label = \"11\" weight = \"11\" ];\npackage_864d6940ac14438961598d5a -> package_bfb0d6f0cb59390b479b08a1 [ label = \"73\" weight = \"73\" ];\npackage_864d6940ac14438961598d5a -> package_e16f87ed4cbaa8972b66b80b [ label = \"5\" weight = \"5\" ];\npackage_864d6940ac14438961598d5a -> package_275b39592e996f9bc7d2bab4 [ label = \"35\" weight = \"35\" ];\npackage_bb20afe0ec6010144ae2060c -> package_bfb0d6f0cb59390b479b08a1 [ label = \"8\" weight = \"8\" ];\npackage_bb20afe0ec6010144ae2060c -> package_864d6940ac14438961598d5a [ label = \"2\" weight = \"2\" ];\npackage_864d6940ac14438961598d5a -> package_8b5bd27cd192f3c043f79d74 [ label = \"33\" weight = \"33\" ];\npackage_864d6940ac14438961598d5a -> package_0b6cea3e7e0dde98e8d142c3 [ label = \"12\" weight = \"12\" ];\npackage_864d6940ac14438961598d5a -> package_869fe932642cb7510df73c8d [ label = \"2\" weight = \"2\" ];\npackage_864d6940ac14438961598d5a -> package_179967d6e66ef95e5ec582dc [ label = \"5\" weight = \"5\" ];\npackage_6da3c08ea2d561edab77673f [label=\"org.hjug.dsm\"];\npackage_5a5b226dc916c25cd94e86c9 [label=\"org.hjug.mavenreport\"];\npackage_d30a7a8d892c5e6113a07e84 [label=\"org.hjug.feedback.arc.pageRank\"];\npackage_d6011c21970de8ae7eafff05 [label=\"org.hjug.metrics.rules\"];\npackage_179967d6e66ef95e5ec582dc [label=\"org.hjug.graphbuilder.metrics\"];\npackage_98c578ab6c4dd833f53d3aee [label=\"org.hjug.graphbuilder.graphbuilder\"];\npackage_8b5bd27cd192f3c043f79d74 [label=\"org.hjug.refactorfirst.report.model\"];\npackage_cc2439ece2ff219a79eb369d [label=\"org.hjug.git\"];\npackage_bb20afe0ec6010144ae2060c [label=\"org.hjug.refactorfirst.report.json\"];\npackage_d36e09db80f0e2bbc4ffd5c7 [label=\"org.hjug.graphbuilder.visitor\"];\npackage_0b6cea3e7e0dde98e8d142c3 [label=\"org.hjug.feedback\"];\npackage_275b39592e996f9bc7d2bab4 [label=\"org.hjug.graphbuilder\" color=red style=filled];\npackage_869fe932642cb7510df73c8d [label=\"org.hjug.metrics\"];\npackage_864d6940ac14438961598d5a [label=\"org.hjug.refactorfirst.report\"];\npackage_e16f87ed4cbaa8972b66b80b [label=\"org.hjug.gdg\"];\npackage_c28460328a6700365ccc109d [label=\"org.hjug.gradlereport\"];\npackage_5770287cc40afd5bd6812d59 [label=\"org.hjug.feedback.arc.exact\"];\npackage_622c04a26e1ba36b6ebca283 [label=\"org.hjug.refactorfirst\"];\npackage_bfb0d6f0cb59390b479b08a1 [label=\"org.hjug.cbc\" color=red style=filled];\npackage_d2f1dd27b2e43b88238a4c05 [label=\"org.hjug.feedback.vertex.kernelized\"];\n}", + "hierarchy" : { + "packages" : [ { + "name" : "org.hjug", + "id" : "cluster_8470465d943ffd5150e2d522", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ { + "name" : "org.hjug.cbc", + "id" : "cluster_bfb0d6f0cb59390b479b08a1", + "nodeId" : "package_bfb0d6f0cb59390b479b08a1", + "renderAsNode" : true, + "needsBreakUp" : true, + "path" : "cost-benefit-calculator/src/main/java/org/hjug/cbc/", + "children" : [ ], + "classes" : [ ] + }, { + "name" : "org.hjug.dsm", + "id" : "cluster_6da3c08ea2d561edab77673f", + "nodeId" : "package_6da3c08ea2d561edab77673f", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "graph-algorithms/src/main/java/org/hjug/dsm/", + "children" : [ ], + "classes" : [ ] + }, { + "name" : "org.hjug.feedback", + "id" : "cluster_0b6cea3e7e0dde98e8d142c3", + "nodeId" : "package_0b6cea3e7e0dde98e8d142c3", + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/", + "children" : [ { + "name" : "org.hjug.feedback.arc", + "id" : "cluster_291a9b47e500445b847479b7", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/", + "children" : [ { + "name" : "org.hjug.feedback.arc.exact", + "id" : "cluster_5770287cc40afd5bd6812d59", + "nodeId" : "package_5770287cc40afd5bd6812d59", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/", + "children" : [ ], + "classes" : [ ] + }, { + "name" : "org.hjug.feedback.arc.pageRank", + "id" : "cluster_d30a7a8d892c5e6113a07e84", + "nodeId" : "package_d30a7a8d892c5e6113a07e84", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/", + "children" : [ ], + "classes" : [ ] + } ], + "classes" : [ ] + }, { + "name" : "org.hjug.feedback.vertex.kernelized", + "id" : "cluster_d2f1dd27b2e43b88238a4c05", + "nodeId" : "package_d2f1dd27b2e43b88238a4c05", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/", + "children" : [ ], + "classes" : [ ] + } ], + "classes" : [ ] + }, { + "name" : "org.hjug.gdg", + "id" : "cluster_e16f87ed4cbaa8972b66b80b", + "nodeId" : "package_e16f87ed4cbaa8972b66b80b", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "graph-data-generator/src/main/java/org/hjug/gdg/", + "children" : [ ], + "classes" : [ ] + }, { + "name" : "org.hjug.git", + "id" : "cluster_cc2439ece2ff219a79eb369d", + "nodeId" : "package_cc2439ece2ff219a79eb369d", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "change-proneness-ranker/src/main/java/org/hjug/git/", + "children" : [ ], + "classes" : [ ] + }, { + "name" : "org.hjug.gradlereport", + "id" : "cluster_c28460328a6700365ccc109d", + "nodeId" : "package_c28460328a6700365ccc109d", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "refactor-first-gradle-plugin/src/main/java/org/hjug/gradlereport/", + "children" : [ ], + "classes" : [ ] + }, { + "name" : "org.hjug.graphbuilder", + "id" : "cluster_275b39592e996f9bc7d2bab4", + "nodeId" : "package_275b39592e996f9bc7d2bab4", + "renderAsNode" : false, + "needsBreakUp" : true, + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/", + "children" : [ { + "name" : "org.hjug.graphbuilder.graphbuilder", + "id" : "cluster_98c578ab6c4dd833f53d3aee", + "nodeId" : "package_98c578ab6c4dd833f53d3aee", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/graphbuilder/", + "children" : [ ], + "classes" : [ ] + }, { + "name" : "org.hjug.graphbuilder.metrics", + "id" : "cluster_179967d6e66ef95e5ec582dc", + "nodeId" : "package_179967d6e66ef95e5ec582dc", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/", + "children" : [ ], + "classes" : [ ] + }, { + "name" : "org.hjug.graphbuilder.visitor", + "id" : "cluster_d36e09db80f0e2bbc4ffd5c7", + "nodeId" : "package_d36e09db80f0e2bbc4ffd5c7", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/", + "children" : [ ], + "classes" : [ ] + } ], + "classes" : [ ] + }, { + "name" : "org.hjug.mavenreport", + "id" : "cluster_5a5b226dc916c25cd94e86c9", + "nodeId" : "package_5a5b226dc916c25cd94e86c9", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "refactor-first-maven-plugin/src/main/java/org/hjug/mavenreport/", + "children" : [ ], + "classes" : [ ] + }, { + "name" : "org.hjug.metrics", + "id" : "cluster_869fe932642cb7510df73c8d", + "nodeId" : "package_869fe932642cb7510df73c8d", + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "effort-ranker/src/main/java/org/hjug/metrics/", + "children" : [ { + "name" : "org.hjug.metrics.rules", + "id" : "cluster_d6011c21970de8ae7eafff05", + "nodeId" : "package_d6011c21970de8ae7eafff05", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "effort-ranker/src/main/java/org/hjug/metrics/rules/", + "children" : [ ], + "classes" : [ ] + } ], + "classes" : [ ] + }, { + "name" : "org.hjug.refactorfirst", + "id" : "cluster_622c04a26e1ba36b6ebca283", + "nodeId" : "package_622c04a26e1ba36b6ebca283", + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "cli/src/main/java/org/hjug/refactorfirst/", + "children" : [ { + "name" : "org.hjug.refactorfirst.report", + "id" : "cluster_864d6940ac14438961598d5a", + "nodeId" : "package_864d6940ac14438961598d5a", + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "report/src/main/java/org/hjug/refactorfirst/report/", + "children" : [ { + "name" : "org.hjug.refactorfirst.report.json", + "id" : "cluster_bb20afe0ec6010144ae2060c", + "nodeId" : "package_bb20afe0ec6010144ae2060c", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "report/src/main/java/org/hjug/refactorfirst/report/json/", + "children" : [ ], + "classes" : [ ] + }, { + "name" : "org.hjug.refactorfirst.report.model", + "id" : "cluster_8b5bd27cd192f3c043f79d74", + "nodeId" : "package_8b5bd27cd192f3c043f79d74", + "renderAsNode" : true, + "needsBreakUp" : false, + "path" : "report/src/main/java/org/hjug/refactorfirst/report/model/", + "children" : [ ], + "classes" : [ ] + } ], + "classes" : [ ] + } ], + "classes" : [ ] + } ], + "classes" : [ ] + } ], + "edges" : [ { + "source" : "package_0b6cea3e7e0dde98e8d142c3", + "target" : "package_6da3c08ea2d561edab77673f", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "package_0b6cea3e7e0dde98e8d142c3", + "target" : "package_d2f1dd27b2e43b88238a4c05", + "weight" : 12, + "markedForRemoval" : true + }, { + "source" : "package_0b6cea3e7e0dde98e8d142c3", + "target" : "package_d30a7a8d892c5e6113a07e84", + "weight" : 3, + "markedForRemoval" : true + }, { + "source" : "package_179967d6e66ef95e5ec582dc", + "target" : "package_275b39592e996f9bc7d2bab4", + "weight" : 16, + "markedForRemoval" : true + }, { + "source" : "package_275b39592e996f9bc7d2bab4", + "target" : "package_179967d6e66ef95e5ec582dc", + "weight" : 12, + "markedForRemoval" : false + }, { + "source" : "package_275b39592e996f9bc7d2bab4", + "target" : "package_98c578ab6c4dd833f53d3aee", + "weight" : 6, + "markedForRemoval" : true + }, { + "source" : "package_5770287cc40afd5bd6812d59", + "target" : "package_0b6cea3e7e0dde98e8d142c3", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "package_5a5b226dc916c25cd94e86c9", + "target" : "package_864d6940ac14438961598d5a", + "weight" : 16, + "markedForRemoval" : false + }, { + "source" : "package_5a5b226dc916c25cd94e86c9", + "target" : "package_bb20afe0ec6010144ae2060c", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "package_622c04a26e1ba36b6ebca283", + "target" : "package_864d6940ac14438961598d5a", + "weight" : 10, + "markedForRemoval" : false + }, { + "source" : "package_622c04a26e1ba36b6ebca283", + "target" : "package_bb20afe0ec6010144ae2060c", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "package_864d6940ac14438961598d5a", + "target" : "package_0b6cea3e7e0dde98e8d142c3", + "weight" : 12, + "markedForRemoval" : false + }, { + "source" : "package_864d6940ac14438961598d5a", + "target" : "package_179967d6e66ef95e5ec582dc", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "package_864d6940ac14438961598d5a", + "target" : "package_275b39592e996f9bc7d2bab4", + "weight" : 84, + "markedForRemoval" : false + }, { + "source" : "package_864d6940ac14438961598d5a", + "target" : "package_869fe932642cb7510df73c8d", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "package_864d6940ac14438961598d5a", + "target" : "package_8b5bd27cd192f3c043f79d74", + "weight" : 81, + "markedForRemoval" : false + }, { + "source" : "package_864d6940ac14438961598d5a", + "target" : "package_bfb0d6f0cb59390b479b08a1", + "weight" : 76, + "markedForRemoval" : false + }, { + "source" : "package_864d6940ac14438961598d5a", + "target" : "package_cc2439ece2ff219a79eb369d", + "weight" : 11, + "markedForRemoval" : false + }, { + "source" : "package_864d6940ac14438961598d5a", + "target" : "package_e16f87ed4cbaa8972b66b80b", + "weight" : 5, + "markedForRemoval" : false + }, { + "source" : "package_869fe932642cb7510df73c8d", + "target" : "package_179967d6e66ef95e5ec582dc", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "package_98c578ab6c4dd833f53d3aee", + "target" : "package_179967d6e66ef95e5ec582dc", + "weight" : 39, + "markedForRemoval" : false + }, { + "source" : "package_98c578ab6c4dd833f53d3aee", + "target" : "package_275b39592e996f9bc7d2bab4", + "weight" : 30, + "markedForRemoval" : false + }, { + "source" : "package_98c578ab6c4dd833f53d3aee", + "target" : "package_d36e09db80f0e2bbc4ffd5c7", + "weight" : 6, + "markedForRemoval" : false + }, { + "source" : "package_bb20afe0ec6010144ae2060c", + "target" : "package_864d6940ac14438961598d5a", + "weight" : 2, + "markedForRemoval" : false + }, { + "source" : "package_bb20afe0ec6010144ae2060c", + "target" : "package_bfb0d6f0cb59390b479b08a1", + "weight" : 8, + "markedForRemoval" : false + }, { + "source" : "package_bfb0d6f0cb59390b479b08a1", + "target" : "package_179967d6e66ef95e5ec582dc", + "weight" : 7, + "markedForRemoval" : false + }, { + "source" : "package_bfb0d6f0cb59390b479b08a1", + "target" : "package_275b39592e996f9bc7d2bab4", + "weight" : 39, + "markedForRemoval" : false + }, { + "source" : "package_bfb0d6f0cb59390b479b08a1", + "target" : "package_6da3c08ea2d561edab77673f", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "package_bfb0d6f0cb59390b479b08a1", + "target" : "package_869fe932642cb7510df73c8d", + "weight" : 49, + "markedForRemoval" : false + }, { + "source" : "package_bfb0d6f0cb59390b479b08a1", + "target" : "package_cc2439ece2ff219a79eb369d", + "weight" : 27, + "markedForRemoval" : false + }, { + "source" : "package_bfb0d6f0cb59390b479b08a1", + "target" : "package_d6011c21970de8ae7eafff05", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "package_c28460328a6700365ccc109d", + "target" : "package_864d6940ac14438961598d5a", + "weight" : 9, + "markedForRemoval" : false + }, { + "source" : "package_c28460328a6700365ccc109d", + "target" : "package_bb20afe0ec6010144ae2060c", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "package_d2f1dd27b2e43b88238a4c05", + "target" : "package_0b6cea3e7e0dde98e8d142c3", + "weight" : 12, + "markedForRemoval" : false + }, { + "source" : "package_d30a7a8d892c5e6113a07e84", + "target" : "package_0b6cea3e7e0dde98e8d142c3", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "package_d36e09db80f0e2bbc4ffd5c7", + "target" : "package_275b39592e996f9bc7d2bab4", + "weight" : 14, + "markedForRemoval" : false + }, { + "source" : "package_e16f87ed4cbaa8972b66b80b", + "target" : "package_bfb0d6f0cb59390b479b08a1", + "weight" : 2, + "markedForRemoval" : false + } ] + }, "hasEdges" : true }, "packageRelationshipsToRemove" : { @@ -67,43 +3320,16 @@ "relationshipsToRemoveCount" : 4, "hasRelationships" : true, "relationships" : [ { - "sourcePackage" : "org.hjug.graphbuilder.metrics", - "targetPackage" : "org.hjug.graphbuilder", - "sourcePackagePath" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/", - "targetPackagePath" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/", - "sourceMarked" : false, - "targetMarked" : true, - "weight" : 1, - "priority" : 1, - "cycleCount" : 1, - "effortRank" : 1, - "classRelationshipsToBreakPackage" : [ { - "sourceClass" : "org.hjug.graphbuilder.metrics.GraphMetricsCollector", - "targetClass" : "org.hjug.graphbuilder.DependencyCollector", - "sourceClassPath" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java", - "targetClassPath" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/DependencyCollector.java", - "simpleSourceClassName" : "GraphMetricsCollector", - "simpleTargetClassName" : "DependencyCollector", - "sourceMarked" : false, - "targetMarked" : false, - "weight" : 1, - "priority" : 0, - "cycleCount" : 0, - "effortRank" : 0, - "alsoRemovesPackageRelationship" : false, - "packageCycleCount" : 0 - } ] - }, { "sourcePackage" : "org.hjug.feedback", "targetPackage" : "org.hjug.feedback.arc.pageRank", "sourcePackagePath" : "graph-algorithms/src/main/java/org/hjug/feedback/", "targetPackagePath" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/", "sourceMarked" : false, "targetMarked" : false, - "weight" : 2, - "priority" : 2, + "weight" : 3, + "priority" : 1, "cycleCount" : 1, - "effortRank" : 2, + "effortRank" : 3, "classRelationshipsToBreakPackage" : [ { "sourceClass" : "org.hjug.feedback.CycleRemovalComputer", "targetClass" : "org.hjug.feedback.arc.pageRank.PageRankFAS", @@ -113,7 +3339,7 @@ "simpleTargetClassName" : "PageRankFAS", "sourceMarked" : false, "targetMarked" : false, - "weight" : 2, + "weight" : 3, "priority" : 0, "cycleCount" : 0, "effortRank" : 0, @@ -128,7 +3354,7 @@ "sourceMarked" : true, "targetMarked" : false, "weight" : 6, - "priority" : 3, + "priority" : 2, "cycleCount" : 1, "effortRank" : 6, "classRelationshipsToBreakPackage" : [ { @@ -169,10 +3395,10 @@ "targetPackagePath" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/", "sourceMarked" : false, "targetMarked" : false, - "weight" : 10, - "priority" : 4, + "weight" : 12, + "priority" : 3, "cycleCount" : 1, - "effortRank" : 10, + "effortRank" : 12, "classRelationshipsToBreakPackage" : [ { "sourceClass" : "org.hjug.feedback.CycleRemovalComputer", "targetClass" : "org.hjug.feedback.vertex.kernelized.DirectedFeedbackVertexSetResult", @@ -197,7 +3423,7 @@ "simpleTargetClassName" : "DirectedFeedbackVertexSetSolver", "sourceMarked" : false, "targetMarked" : false, - "weight" : 2, + "weight" : 3, "priority" : 0, "cycleCount" : 0, "effortRank" : 0, @@ -212,7 +3438,7 @@ "simpleTargetClassName" : "EnhancedParameterComputer", "sourceMarked" : false, "targetMarked" : false, - "weight" : 2, + "weight" : 3, "priority" : 0, "cycleCount" : 0, "effortRank" : 0, @@ -234,6 +3460,48 @@ "alsoRemovesPackageRelationship" : false, "packageCycleCount" : 0 } ] + }, { + "sourcePackage" : "org.hjug.graphbuilder.metrics", + "targetPackage" : "org.hjug.graphbuilder", + "sourcePackagePath" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/", + "targetPackagePath" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/", + "sourceMarked" : false, + "targetMarked" : true, + "weight" : 16, + "priority" : 4, + "cycleCount" : 1, + "effortRank" : 16, + "classRelationshipsToBreakPackage" : [ { + "sourceClass" : "org.hjug.graphbuilder.metrics.GraphMetricsCollector", + "targetClass" : "org.hjug.graphbuilder.DependencyCollector", + "sourceClassPath" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java", + "targetClassPath" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/DependencyCollector.java", + "simpleSourceClassName" : "GraphMetricsCollector", + "simpleTargetClassName" : "DependencyCollector", + "sourceMarked" : false, + "targetMarked" : false, + "weight" : 1, + "priority" : 0, + "cycleCount" : 0, + "effortRank" : 0, + "alsoRemovesPackageRelationship" : false, + "packageCycleCount" : 0 + }, { + "sourceClass" : "org.hjug.graphbuilder.metrics.GraphMetricsCollector", + "targetClass" : "org.hjug.graphbuilder.VertexInfo", + "sourceClassPath" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java", + "targetClassPath" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/VertexInfo.java", + "simpleSourceClassName" : "GraphMetricsCollector", + "simpleTargetClassName" : "VertexInfo", + "sourceMarked" : false, + "targetMarked" : false, + "weight" : 15, + "priority" : 0, + "cycleCount" : 0, + "effortRank" : 0, + "alsoRemovesPackageRelationship" : false, + "packageCycleCount" : 0 + } ] } ] }, "hasDisharmonies" : true, @@ -284,8 +3552,8 @@ "borderColor" : "rgb(39, 174, 96)", "path" : "test-resources/src/main/resources/Attributes.java" } ], - "yaxisLabel" : "Relative churn (impact)", - "xaxisLabel" : "Effort to refactor" + "xaxisLabel" : "Effort to refactor", + "yaxisLabel" : "Relative churn (impact)" }, "table" : { "headers" : [ "Class", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], @@ -404,8 +3672,8 @@ "borderColor" : "rgb(39, 174, 96)", "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" } ], - "yaxisLabel" : "Relative churn (impact)", - "xaxisLabel" : "Effort to refactor" + "xaxisLabel" : "Effort to refactor", + "yaxisLabel" : "Relative churn (impact)" }, "table" : { "headers" : [ "Class", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], @@ -427,11 +3695,11 @@ "align" : "right", "path" : null }, { - "content" : "10/5/26, 12:56 PM", + "content" : "10/20/26, 5:35 PM", "align" : "right", "path" : null }, { - "content" : "19", + "content" : "21", "align" : "right", "path" : null } ] @@ -474,53 +3742,53 @@ "chart" : { "canvasId" : "chart_RPB", "bubbles" : [ { - "id" : "AttributeHandlerAndSorter.java", - "label" : "AttributeHandlerAndSorter.java", + "id" : "HtmlReport.java", + "label" : "HtmlReport.java", "x" : 1, - "y" : 2, + "y" : 4, "r" : 24, "priority" : 1, "effortRank" : 1, - "changePronenessRank" : 2, + "changePronenessRank" : 4, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", - "path" : "test-resources/src/main/resources/AttributeHandlerAndSorter.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java" }, { - "id" : "AttributeHandler2.java", - "label" : "AttributeHandler2.java", - "x" : 2, - "y" : 3, + "id" : "JsonGenerator.java", + "label" : "JsonGenerator.java", + "x" : 3, + "y" : 5, "r" : 20, "priority" : 2, - "effortRank" : 2, - "changePronenessRank" : 3, + "effortRank" : 3, + "changePronenessRank" : 5, "color" : "rgba(186, 92, 63, 0.75)", "borderColor" : "rgb(186, 92, 63)", - "path" : "test-resources/src/main/resources/AttributeHandler2.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" }, { - "id" : "HtmlReport.java", - "label" : "HtmlReport.java", - "x" : 3, - "y" : 4, + "id" : "AttributeHandlerAndSorter.java", + "label" : "AttributeHandlerAndSorter.java", + "x" : 1, + "y" : 2, "r" : 15, "priority" : 3, - "effortRank" : 3, - "changePronenessRank" : 4, + "effortRank" : 1, + "changePronenessRank" : 2, "color" : "rgba(137, 119, 74, 0.75)", "borderColor" : "rgb(137, 119, 74)", - "path" : "report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java" + "path" : "test-resources/src/main/resources/AttributeHandlerAndSorter.java" }, { - "id" : "JsonGenerator.java", - "label" : "JsonGenerator.java", - "x" : 4, - "y" : 5, + "id" : "AttributeHandler2.java", + "label" : "AttributeHandler2.java", + "x" : 2, + "y" : 3, "r" : 11, "priority" : 4, - "effortRank" : 4, - "changePronenessRank" : 5, + "effortRank" : 2, + "changePronenessRank" : 3, "color" : "rgba(88, 147, 85, 0.75)", "borderColor" : "rgb(88, 147, 85)", - "path" : "report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" + "path" : "test-resources/src/main/resources/AttributeHandler2.java" }, { "id" : "AttributeHandler.java", "label" : "AttributeHandler.java", @@ -534,22 +3802,22 @@ "borderColor" : "rgb(39, 174, 96)", "path" : "test-resources/src/main/resources/AttributeHandler.java" } ], - "yaxisLabel" : "Relative churn (impact)", - "xaxisLabel" : "Effort to refactor" + "xaxisLabel" : "Effort to refactor", + "yaxisLabel" : "Relative churn (impact)" }, "table" : { "headers" : [ "Class", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], "rows" : [ { "cells" : [ { - "content" : "AttributeHandlerAndSorter.java", + "content" : "HtmlReport.java", "align" : "left", - "path" : "test-resources/src/main/resources/AttributeHandlerAndSorter.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java" }, { "content" : "1", "align" : "right", "path" : null }, { - "content" : "2", + "content" : "4", "align" : "right", "path" : null }, { @@ -557,89 +3825,89 @@ "align" : "right", "path" : null }, { - "content" : "10/1/20, 8:46 AM", + "content" : "10/20/26, 5:35 PM", "align" : "right", "path" : null }, { - "content" : "1", + "content" : "67", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "AttributeHandler2.java", + "content" : "JsonGenerator.java", "align" : "left", - "path" : "test-resources/src/main/resources/AttributeHandler2.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" }, { "content" : "2", "align" : "right", "path" : null }, { - "content" : "3", + "content" : "5", "align" : "right", "path" : null }, { - "content" : "2", + "content" : "3", "align" : "right", "path" : null }, { - "content" : "10/1/20, 8:46 AM", + "content" : "10/20/26, 5:35 PM", "align" : "right", "path" : null }, { - "content" : "1", + "content" : "21", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "HtmlReport.java", + "content" : "AttributeHandlerAndSorter.java", "align" : "left", - "path" : "report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java" + "path" : "test-resources/src/main/resources/AttributeHandlerAndSorter.java" }, { "content" : "3", "align" : "right", "path" : null }, { - "content" : "4", + "content" : "2", "align" : "right", "path" : null }, { - "content" : "3", + "content" : "1", "align" : "right", "path" : null }, { - "content" : "10/3/26, 4:43 PM", + "content" : "10/1/20, 8:46 AM", "align" : "right", "path" : null }, { - "content" : "64", + "content" : "1", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "JsonGenerator.java", + "content" : "AttributeHandler2.java", "align" : "left", - "path" : "report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" + "path" : "test-resources/src/main/resources/AttributeHandler2.java" }, { "content" : "4", "align" : "right", "path" : null }, { - "content" : "5", + "content" : "3", "align" : "right", "path" : null }, { - "content" : "4", + "content" : "2", "align" : "right", "path" : null }, { - "content" : "10/5/26, 12:56 PM", + "content" : "10/1/20, 8:46 AM", "align" : "right", "path" : null }, { - "content" : "19", + "content" : "1", "align" : "right", "path" : null } ] @@ -682,46 +3950,46 @@ "chart" : { "canvasId" : "chart_TB", "bubbles" : [ { - "id" : "AttributeHandler2.java", - "label" : "AttributeHandler2.java", + "id" : "HtmlReport.java", + "label" : "HtmlReport.java", "x" : 1, - "y" : 1, + "y" : 2, "r" : 24, "priority" : 1, "effortRank" : 1, - "changePronenessRank" : 1, + "changePronenessRank" : 2, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", - "path" : "test-resources/src/main/resources/AttributeHandler2.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java" }, { - "id" : "HtmlReport.java", - "label" : "HtmlReport.java", - "x" : 2, - "y" : 2, + "id" : "AttributeHandler2.java", + "label" : "AttributeHandler2.java", + "x" : 1, + "y" : 1, "r" : 6, "priority" : 2, - "effortRank" : 2, - "changePronenessRank" : 2, + "effortRank" : 1, + "changePronenessRank" : 1, "color" : "rgba(39, 174, 96, 0.75)", "borderColor" : "rgb(39, 174, 96)", - "path" : "report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java" + "path" : "test-resources/src/main/resources/AttributeHandler2.java" } ], - "yaxisLabel" : "Relative churn (impact)", - "xaxisLabel" : "Effort to refactor" + "xaxisLabel" : "Effort to refactor", + "yaxisLabel" : "Relative churn (impact)" }, "table" : { "headers" : [ "Class", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], "rows" : [ { "cells" : [ { - "content" : "AttributeHandler2.java", + "content" : "HtmlReport.java", "align" : "left", - "path" : "test-resources/src/main/resources/AttributeHandler2.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java" }, { "content" : "1", "align" : "right", "path" : null }, { - "content" : "1", + "content" : "2", "align" : "right", "path" : null }, { @@ -729,37 +3997,37 @@ "align" : "right", "path" : null }, { - "content" : "10/1/20, 8:46 AM", + "content" : "10/20/26, 5:35 PM", "align" : "right", "path" : null }, { - "content" : "1", + "content" : "67", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "HtmlReport.java", + "content" : "AttributeHandler2.java", "align" : "left", - "path" : "report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java" + "path" : "test-resources/src/main/resources/AttributeHandler2.java" }, { "content" : "2", "align" : "right", "path" : null }, { - "content" : "2", + "content" : "1", "align" : "right", "path" : null }, { - "content" : "2", + "content" : "1", "align" : "right", "path" : null }, { - "content" : "10/3/26, 4:43 PM", + "content" : "10/1/20, 8:46 AM", "align" : "right", "path" : null }, { - "content" : "64", + "content" : "1", "align" : "right", "path" : null } ] @@ -836,8 +4104,8 @@ "borderColor" : "rgb(39, 174, 96)", "path" : "test-resources/src/main/resources/AttributeHandler2.java" } ], - "yaxisLabel" : "Relative churn (impact)", - "xaxisLabel" : "Effort to refactor" + "xaxisLabel" : "Effort to refactor", + "yaxisLabel" : "Relative churn (impact)" }, "table" : { "headers" : [ "Class", "Priority", "Change Proneness Rank", "Effort Rank", "Duplicate Partners", "Most Recent Commit Date", "Commit Count" ], @@ -1007,11 +4275,11 @@ "id" : "CompositeGraphBuilder.java", "label" : "CompositeGraphBuilder.java", "x" : 1, - "y" : 9, + "y" : 10, "r" : 24, "priority" : 1, "effortRank" : 1, - "changePronenessRank" : 9, + "changePronenessRank" : 10, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" @@ -1055,11 +4323,11 @@ "id" : "DisharmonyDetector.java", "label" : "DisharmonyDetector.java", "x" : 6, - "y" : 10, + "y" : 9, "r" : 17, "priority" : 5, "effortRank" : 6, - "changePronenessRank" : 10, + "changePronenessRank" : 9, "color" : "rgba(157, 108, 70, 0.75)", "borderColor" : "rgb(157, 108, 70)", "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" @@ -1136,8 +4404,8 @@ "borderColor" : "rgb(39, 174, 96)", "path" : "test-resources/src/main/resources/AttributeHandler.java" } ], - "yaxisLabel" : "Relative churn (impact)", - "xaxisLabel" : "Effort to refactor" + "xaxisLabel" : "Effort to refactor", + "yaxisLabel" : "Relative churn (impact)" }, "table" : { "headers" : [ "Class", "Method", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], @@ -1155,7 +4423,7 @@ "align" : "right", "path" : null }, { - "content" : "9", + "content" : "10", "align" : "right", "path" : null }, { @@ -1163,11 +4431,11 @@ "align" : "right", "path" : null }, { - "content" : "9/5/26, 1:41 PM", + "content" : "10/17/26, 8:36 AM", "align" : "right", "path" : null }, { - "content" : "8", + "content" : "10", "align" : "right", "path" : null } ] @@ -1275,7 +4543,7 @@ "align" : "right", "path" : null }, { - "content" : "10", + "content" : "9", "align" : "right", "path" : null }, { @@ -1313,11 +4581,11 @@ "align" : "right", "path" : null }, { - "content" : "10/5/26, 12:56 PM", + "content" : "10/20/26, 5:35 PM", "align" : "right", "path" : null }, { - "content" : "19", + "content" : "21", "align" : "right", "path" : null } ] @@ -1480,7 +4748,7 @@ "methodLevel" : true, "problem" : "Method is more interested in data in other classes than its own class.", "solution" : "Move the method (or part of the method) to the class where it uses the most data.", - "maxPriority" : 6, + "maxPriority" : 7, "chart" : { "canvasId" : "chart_FEATURE_ENVY", "bubbles" : [ { @@ -1499,49 +4767,61 @@ "id" : "JsonGenerator.java", "label" : "JsonGenerator.java", "x" : 4, - "y" : 6, - "r" : 20, + "y" : 7, + "r" : 21, "priority" : 2, "effortRank" : 4, - "changePronenessRank" : 6, - "color" : "rgba(196, 86, 61, 0.75)", - "borderColor" : "rgb(196, 86, 61)", + "changePronenessRank" : 7, + "color" : "rgba(202, 82, 59, 0.75)", + "borderColor" : "rgb(202, 82, 59)", "path" : "report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" + }, { + "id" : "HierarchyBuilder.java", + "label" : "HierarchyBuilder.java", + "x" : 4, + "y" : 6, + "r" : 18, + "priority" : 3, + "effortRank" : 4, + "changePronenessRank" : 6, + "color" : "rgba(170, 101, 67, 0.75)", + "borderColor" : "rgb(170, 101, 67)", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/HierarchyBuilder.java" }, { "id" : "MetricsVisitorLogic.java", "label" : "MetricsVisitorLogic.java", "x" : 3, "y" : 4, - "r" : 17, - "priority" : 3, + "r" : 15, + "priority" : 4, "effortRank" : 3, "changePronenessRank" : 4, - "color" : "rgba(157, 108, 70, 0.75)", - "borderColor" : "rgb(157, 108, 70)", + "color" : "rgba(137, 119, 74, 0.75)", + "borderColor" : "rgb(137, 119, 74)", "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" }, { "id" : "AttributeHandlerAndSorter.java", "label" : "AttributeHandlerAndSorter.java", "x" : 2, "y" : 2, - "r" : 13, - "priority" : 4, + "r" : 12, + "priority" : 5, "effortRank" : 2, "changePronenessRank" : 2, - "color" : "rgba(117, 130, 78, 0.75)", - "borderColor" : "rgb(117, 130, 78)", + "color" : "rgba(104, 137, 81, 0.75)", + "borderColor" : "rgb(104, 137, 81)", "path" : "test-resources/src/main/resources/AttributeHandlerAndSorter.java" }, { "id" : "MetricsVisitorLogic.java", "label" : "MetricsVisitorLogic.java", "x" : 4, "y" : 4, - "r" : 10, - "priority" : 5, + "r" : 9, + "priority" : 6, "effortRank" : 4, "changePronenessRank" : 4, - "color" : "rgba(78, 152, 87, 0.75)", - "borderColor" : "rgb(78, 152, 87)", + "color" : "rgba(72, 156, 89, 0.75)", + "borderColor" : "rgb(72, 156, 89)", "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" }, { "id" : "AttributeHandler.java", @@ -1549,15 +4829,15 @@ "x" : 2, "y" : 1, "r" : 6, - "priority" : 6, + "priority" : 7, "effortRank" : 2, "changePronenessRank" : 1, "color" : "rgba(39, 174, 96, 0.75)", "borderColor" : "rgb(39, 174, 96)", "path" : "test-resources/src/main/resources/AttributeHandler.java" } ], - "yaxisLabel" : "Relative churn (impact)", - "xaxisLabel" : "Effort to refactor" + "xaxisLabel" : "Effort to refactor", + "yaxisLabel" : "Relative churn (impact)" }, "table" : { "headers" : [ "Class", "Method", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], @@ -1604,6 +4884,36 @@ "content" : "2", "align" : "right", "path" : null + }, { + "content" : "7", + "align" : "right", + "path" : null + }, { + "content" : "4", + "align" : "right", + "path" : null + }, { + "content" : "10/20/26, 5:35 PM", + "align" : "right", + "path" : null + }, { + "content" : "21", + "align" : "right", + "path" : null + } ] + }, { + "cells" : [ { + "content" : "HierarchyBuilder.java", + "align" : "left", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/HierarchyBuilder.java" + }, { + "content" : "toDto(HierarchyBuilder$Pkg)", + "align" : "left", + "path" : null + }, { + "content" : "3", + "align" : "right", + "path" : null }, { "content" : "6", "align" : "right", @@ -1613,11 +4923,11 @@ "align" : "right", "path" : null }, { - "content" : "10/5/26, 12:56 PM", + "content" : "10/20/26, 5:35 PM", "align" : "right", "path" : null }, { - "content" : "19", + "content" : "1", "align" : "right", "path" : null } ] @@ -1631,7 +4941,7 @@ "align" : "left", "path" : null }, { - "content" : "3", + "content" : "4", "align" : "right", "path" : null }, { @@ -1661,7 +4971,7 @@ "align" : "left", "path" : null }, { - "content" : "4", + "content" : "5", "align" : "right", "path" : null }, { @@ -1691,7 +5001,7 @@ "align" : "left", "path" : null }, { - "content" : "5", + "content" : "6", "align" : "right", "path" : null }, { @@ -1721,7 +5031,7 @@ "align" : "left", "path" : null }, { - "content" : "6", + "content" : "7", "align" : "right", "path" : null }, { @@ -1756,47 +5066,47 @@ "bubbles" : [ { "id" : "SimpleHtmlReport.java", "label" : "SimpleHtmlReport.java", - "x" : 5, + "x" : 4, "y" : 15, "r" : 24, "priority" : 1, - "effortRank" : 5, + "effortRank" : 4, "changePronenessRank" : 15, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", "path" : "report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java" }, { - "id" : "CompositeGraphBuilder.java", - "label" : "CompositeGraphBuilder.java", - "x" : 2, - "y" : 11, + "id" : "SimpleHtmlReport.java", + "label" : "SimpleHtmlReport.java", + "x" : 6, + "y" : 15, "r" : 23, "priority" : 2, - "effortRank" : 2, - "changePronenessRank" : 11, + "effortRank" : 6, + "changePronenessRank" : 15, "color" : "rgba(223, 71, 55, 0.75)", "borderColor" : "rgb(223, 71, 55)", - "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java" }, { - "id" : "SimpleHtmlReport.java", - "label" : "SimpleHtmlReport.java", - "x" : 8, - "y" : 15, + "id" : "CompositeGraphBuilder.java", + "label" : "CompositeGraphBuilder.java", + "x" : 2, + "y" : 10, "r" : 22, "priority" : 3, - "effortRank" : 8, - "changePronenessRank" : 15, + "effortRank" : 2, + "changePronenessRank" : 10, "color" : "rgba(211, 78, 58, 0.75)", "borderColor" : "rgb(211, 78, 58)", - "path" : "report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java" + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" }, { "id" : "SimpleHtmlReport.java", "label" : "SimpleHtmlReport.java", - "x" : 9, + "x" : 8, "y" : 15, "r" : 21, "priority" : 4, - "effortRank" : 9, + "effortRank" : 8, "changePronenessRank" : 15, "color" : "rgba(198, 85, 60, 0.75)", "borderColor" : "rgb(198, 85, 60)", @@ -1804,143 +5114,143 @@ }, { "id" : "JsonGenerator.java", "label" : "JsonGenerator.java", - "x" : 12, + "x" : 11, "y" : 17, "r" : 20, "priority" : 5, - "effortRank" : 12, + "effortRank" : 11, "changePronenessRank" : 17, "color" : "rgba(186, 92, 63, 0.75)", "borderColor" : "rgb(186, 92, 63)", "path" : "report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" }, { - "id" : "OptimalBackEdgeRemover.java", - "label" : "OptimalBackEdgeRemover.java", - "x" : 1, - "y" : 5, + "id" : "HierarchyBuilder.java", + "label" : "HierarchyBuilder.java", + "x" : 7, + "y" : 12, "r" : 18, "priority" : 6, - "effortRank" : 1, - "changePronenessRank" : 5, + "effortRank" : 7, + "changePronenessRank" : 12, "color" : "rgba(174, 98, 66, 0.75)", "borderColor" : "rgb(174, 98, 66)", - "path" : "graph-algorithms/src/main/java/org/hjug/dsm/OptimalBackEdgeRemover.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/HierarchyBuilder.java" }, { - "id" : "PageRankFAS.java", - "label" : "PageRankFAS.java", - "x" : 5, - "y" : 9, + "id" : "JsonGenerator.java", + "label" : "JsonGenerator.java", + "x" : 12, + "y" : 17, "r" : 17, "priority" : 7, - "effortRank" : 5, - "changePronenessRank" : 9, + "effortRank" : 12, + "changePronenessRank" : 17, "color" : "rgba(162, 105, 69, 0.75)", "borderColor" : "rgb(162, 105, 69)", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" }, { - "id" : "FeedbackVertexSetSolver.java", - "label" : "FeedbackVertexSetSolver.java", - "x" : 5, - "y" : 8, + "id" : "OptimalBackEdgeRemover.java", + "label" : "OptimalBackEdgeRemover.java", + "x" : 1, + "y" : 5, "r" : 16, "priority" : 8, - "effortRank" : 5, - "changePronenessRank" : 8, + "effortRank" : 1, + "changePronenessRank" : 5, "color" : "rgba(149, 112, 71, 0.75)", "borderColor" : "rgb(149, 112, 71)", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/approximate/FeedbackVertexSetSolver.java" + "path" : "graph-algorithms/src/main/java/org/hjug/dsm/OptimalBackEdgeRemover.java" }, { - "id" : "CompositeGraphBuilder.java", - "label" : "CompositeGraphBuilder.java", - "x" : 8, + "id" : "VertexInfoHydrator.java", + "label" : "VertexInfoHydrator.java", + "x" : 7, "y" : 11, "r" : 15, "priority" : 9, - "effortRank" : 8, + "effortRank" : 7, "changePronenessRank" : 11, "color" : "rgba(137, 119, 74, 0.75)", "borderColor" : "rgb(137, 119, 74)", - "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/VertexInfoHydrator.java" }, { - "id" : "JsonGenerator.java", - "label" : "JsonGenerator.java", - "x" : 14, - "y" : 17, + "id" : "PageRankFAS.java", + "label" : "PageRankFAS.java", + "x" : 4, + "y" : 7, "r" : 14, "priority" : 10, - "effortRank" : 14, - "changePronenessRank" : 17, + "effortRank" : 4, + "changePronenessRank" : 7, "color" : "rgba(125, 126, 77, 0.75)", "borderColor" : "rgb(125, 126, 77)", - "path" : "report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java" }, { - "id" : "TreewidthComputer.java", - "label" : "TreewidthComputer.java", - "x" : 4, - "y" : 6, + "id" : "CompositeGraphBuilder.java", + "label" : "CompositeGraphBuilder.java", + "x" : 8, + "y" : 10, "r" : 13, "priority" : 11, - "effortRank" : 4, - "changePronenessRank" : 6, + "effortRank" : 8, + "changePronenessRank" : 10, "color" : "rgba(113, 133, 80, 0.75)", "borderColor" : "rgb(113, 133, 80)", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" }, { - "id" : "DirectedFeedbackVertexSetSolver.java", - "label" : "DirectedFeedbackVertexSetSolver.java", - "x" : 6, - "y" : 7, + "id" : "MetricsVisitorLogic.java", + "label" : "MetricsVisitorLogic.java", + "x" : 3, + "y" : 4, "r" : 12, "priority" : 12, - "effortRank" : 6, - "changePronenessRank" : 7, + "effortRank" : 3, + "changePronenessRank" : 4, "color" : "rgba(100, 140, 82, 0.75)", "borderColor" : "rgb(100, 140, 82)", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" }, { - "id" : "DisharmonyDetector.java", - "label" : "DisharmonyDetector.java", - "x" : 13, - "y" : 12, + "id" : "FeedbackVertexSetSolver.java", + "label" : "FeedbackVertexSetSolver.java", + "x" : 5, + "y" : 6, "r" : 11, "priority" : 13, - "effortRank" : 13, - "changePronenessRank" : 12, + "effortRank" : 5, + "changePronenessRank" : 6, "color" : "rgba(88, 147, 85, 0.75)", "borderColor" : "rgb(88, 147, 85)", - "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/approximate/FeedbackVertexSetSolver.java" }, { "id" : "MinimumFeedbackArcSetSolver.java", "label" : "MinimumFeedbackArcSetSolver.java", - "x" : 3, + "x" : 2, "y" : 1, "r" : 9, "priority" : 14, - "effortRank" : 3, + "effortRank" : 2, "changePronenessRank" : 1, "color" : "rgba(76, 153, 88, 0.75)", "borderColor" : "rgb(76, 153, 88)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" }, { - "id" : "MetricsVisitorLogic.java", - "label" : "MetricsVisitorLogic.java", - "x" : 7, - "y" : 4, + "id" : "DisharmonyDetector.java", + "label" : "DisharmonyDetector.java", + "x" : 11, + "y" : 8, "r" : 8, "priority" : 15, - "effortRank" : 7, - "changePronenessRank" : 4, + "effortRank" : 11, + "changePronenessRank" : 8, "color" : "rgba(64, 160, 91, 0.75)", "borderColor" : "rgb(64, 160, 91)", - "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" }, { "id" : "MetricsVisitorLogic.java", "label" : "MetricsVisitorLogic.java", - "x" : 10, + "x" : 9, "y" : 4, "r" : 7, "priority" : 16, - "effortRank" : 10, + "effortRank" : 9, "changePronenessRank" : 4, "color" : "rgba(51, 167, 93, 0.75)", "borderColor" : "rgb(51, 167, 93)", @@ -1948,18 +5258,18 @@ }, { "id" : "MetricsVisitorLogic.java", "label" : "MetricsVisitorLogic.java", - "x" : 11, + "x" : 10, "y" : 4, "r" : 6, "priority" : 17, - "effortRank" : 11, + "effortRank" : 10, "changePronenessRank" : 4, "color" : "rgba(39, 174, 96, 0.75)", "borderColor" : "rgb(39, 174, 96)", "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" } ], - "yaxisLabel" : "Relative churn (impact)", - "xaxisLabel" : "Effort to refactor" + "xaxisLabel" : "Effort to refactor", + "yaxisLabel" : "Relative churn (impact)" }, "table" : { "headers" : [ "Class", "Method", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], @@ -1981,25 +5291,25 @@ "align" : "right", "path" : null }, { - "content" : "5", + "content" : "4", "align" : "right", "path" : null }, { - "content" : "10/4/26, 2:29 PM", + "content" : "10/20/26, 5:35 PM", "align" : "right", "path" : null }, { - "content" : "99", + "content" : "101", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "CompositeGraphBuilder.java", + "content" : "SimpleHtmlReport.java", "align" : "left", - "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java" }, { - "content" : "reconcileUnattributedVertices(Unknown,Unknown,Map<String,String>)", + "content" : "renderDisharmonyInfo(String,SimpleHtmlReport$DisharmonySpec,boolean,List<RankedDisharmony>)", "align" : "left", "path" : null }, { @@ -2007,29 +5317,29 @@ "align" : "right", "path" : null }, { - "content" : "11", + "content" : "15", "align" : "right", "path" : null }, { - "content" : "2", + "content" : "6", "align" : "right", "path" : null }, { - "content" : "9/5/26, 1:41 PM", + "content" : "10/20/26, 5:35 PM", "align" : "right", "path" : null }, { - "content" : "8", + "content" : "101", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "SimpleHtmlReport.java", + "content" : "CompositeGraphBuilder.java", "align" : "left", - "path" : "report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java" + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" }, { - "content" : "renderDisharmonyInfo(String,SimpleHtmlReport$DisharmonySpec,boolean,List<RankedDisharmony>)", + "content" : "reconcileUnattributedVertices(Unknown,Unknown,Map<String,String>)", "align" : "left", "path" : null }, { @@ -2037,19 +5347,19 @@ "align" : "right", "path" : null }, { - "content" : "15", + "content" : "10", "align" : "right", "path" : null }, { - "content" : "8", + "content" : "2", "align" : "right", "path" : null }, { - "content" : "10/4/26, 2:29 PM", + "content" : "10/17/26, 8:36 AM", "align" : "right", "path" : null }, { - "content" : "99", + "content" : "10", "align" : "right", "path" : null } ] @@ -2071,15 +5381,15 @@ "align" : "right", "path" : null }, { - "content" : "9", + "content" : "8", "align" : "right", "path" : null }, { - "content" : "10/4/26, 2:29 PM", + "content" : "10/20/26, 5:35 PM", "align" : "right", "path" : null }, { - "content" : "99", + "content" : "101", "align" : "right", "path" : null } ] @@ -2101,25 +5411,25 @@ "align" : "right", "path" : null }, { - "content" : "12", + "content" : "11", "align" : "right", "path" : null }, { - "content" : "10/5/26, 12:56 PM", + "content" : "10/20/26, 5:35 PM", "align" : "right", "path" : null }, { - "content" : "19", + "content" : "21", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "OptimalBackEdgeRemover.java", + "content" : "HierarchyBuilder.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/dsm/OptimalBackEdgeRemover.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/HierarchyBuilder.java" }, { - "content" : "findOptimalBackEdgesToRemove()", + "content" : "pruneAndCollapse(HierarchyBuilder$Pkg)", "align" : "left", "path" : null }, { @@ -2127,29 +5437,29 @@ "align" : "right", "path" : null }, { - "content" : "5", + "content" : "12", "align" : "right", "path" : null }, { - "content" : "1", + "content" : "7", "align" : "right", "path" : null }, { - "content" : "8/19/26, 7:20 PM", + "content" : "10/20/26, 5:35 PM", "align" : "right", "path" : null }, { - "content" : "2", + "content" : "1", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "PageRankFAS.java", + "content" : "JsonGenerator.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" }, { - "content" : "computePageRank(LineDigraph<V,E>)", + "content" : "generateReportData(boolean,int,boolean,boolean,String,String,String,File)", "align" : "left", "path" : null }, { @@ -2157,29 +5467,29 @@ "align" : "right", "path" : null }, { - "content" : "9", + "content" : "17", "align" : "right", "path" : null }, { - "content" : "5", + "content" : "12", "align" : "right", "path" : null }, { - "content" : "10/4/26, 5:04 PM", + "content" : "10/20/26, 5:35 PM", "align" : "right", "path" : null }, { - "content" : "6", + "content" : "21", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "FeedbackVertexSetSolver.java", + "content" : "OptimalBackEdgeRemover.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/approximate/FeedbackVertexSetSolver.java" + "path" : "graph-algorithms/src/main/java/org/hjug/dsm/OptimalBackEdgeRemover.java" }, { - "content" : "solveRecursive(Unknown,Set<V>)", + "content" : "findOptimalBackEdgesToRemove()", "align" : "left", "path" : null }, { @@ -2187,29 +5497,29 @@ "align" : "right", "path" : null }, { - "content" : "8", + "content" : "5", "align" : "right", "path" : null }, { - "content" : "5", + "content" : "1", "align" : "right", "path" : null }, { - "content" : "8/26/26, 7:48 PM", + "content" : "8/19/26, 7:20 PM", "align" : "right", "path" : null }, { - "content" : "4", + "content" : "2", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "CompositeGraphBuilder.java", + "content" : "VertexInfoHydrator.java", "align" : "left", - "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/VertexInfoHydrator.java" }, { - "content" : "getEnclosingClassFqn(String)", + "content" : "directMemberPackageName(String)", "align" : "left", "path" : null }, { @@ -2221,25 +5531,25 @@ "align" : "right", "path" : null }, { - "content" : "8", + "content" : "7", "align" : "right", "path" : null }, { - "content" : "9/5/26, 1:41 PM", + "content" : "10/17/26, 8:36 AM", "align" : "right", "path" : null }, { - "content" : "8", + "content" : "2", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "JsonGenerator.java", + "content" : "PageRankFAS.java", "align" : "left", - "path" : "report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java" }, { - "content" : "generateReportData(boolean,int,boolean,boolean,String,String,String,File)", + "content" : "computePageRank(LineDigraph<V,E>)", "align" : "left", "path" : null }, { @@ -2247,29 +5557,29 @@ "align" : "right", "path" : null }, { - "content" : "17", + "content" : "7", "align" : "right", "path" : null }, { - "content" : "14", + "content" : "4", "align" : "right", "path" : null }, { - "content" : "10/5/26, 12:56 PM", + "content" : "10/4/26, 5:04 PM", "align" : "right", "path" : null }, { - "content" : "19", + "content" : "6", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "TreewidthComputer.java", + "content" : "CompositeGraphBuilder.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" }, { - "content" : "minDegreeEliminationTreewidth(Unknown)", + "content" : "getEnclosingClassFqn(String)", "align" : "left", "path" : null }, { @@ -2277,29 +5587,29 @@ "align" : "right", "path" : null }, { - "content" : "6", + "content" : "10", "align" : "right", "path" : null }, { - "content" : "4", + "content" : "8", "align" : "right", "path" : null }, { - "content" : "7/12/26, 3:24 PM", + "content" : "10/17/26, 8:36 AM", "align" : "right", "path" : null }, { - "content" : "2", + "content" : "10", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "DirectedFeedbackVertexSetSolver.java", + "content" : "MetricsVisitorLogic.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" }, { - "content" : "computeMinimumVertexCut(V,Set<V>,int)", + "content" : "handleMemberReference(MetricsVisitorState,GraphMetricsCollector,Unknown)", "align" : "left", "path" : null }, { @@ -2307,29 +5617,29 @@ "align" : "right", "path" : null }, { - "content" : "7", + "content" : "4", "align" : "right", "path" : null }, { - "content" : "6", + "content" : "3", "align" : "right", "path" : null }, { - "content" : "8/26/26, 7:48 PM", + "content" : "8/19/26, 7:20 PM", "align" : "right", "path" : null }, { - "content" : "3", + "content" : "1", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "DisharmonyDetector.java", + "content" : "FeedbackVertexSetSolver.java", "align" : "left", - "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/approximate/FeedbackVertexSetSolver.java" }, { - "content" : "detectSignificantDuplication(List<ClassMetrics>)", + "content" : "solveRecursive(Unknown,Set<V>)", "align" : "left", "path" : null }, { @@ -2337,19 +5647,19 @@ "align" : "right", "path" : null }, { - "content" : "12", + "content" : "6", "align" : "right", "path" : null }, { - "content" : "13", + "content" : "5", "align" : "right", "path" : null }, { - "content" : "9/5/26, 1:41 PM", + "content" : "8/26/26, 7:48 PM", "align" : "right", "path" : null }, { - "content" : "15", + "content" : "4", "align" : "right", "path" : null } ] @@ -2371,7 +5681,7 @@ "align" : "right", "path" : null }, { - "content" : "3", + "content" : "2", "align" : "right", "path" : null }, { @@ -2385,11 +5695,11 @@ } ] }, { "cells" : [ { - "content" : "MetricsVisitorLogic.java", + "content" : "DisharmonyDetector.java", "align" : "left", - "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" }, { - "content" : "handleMemberReference(MetricsVisitorState,GraphMetricsCollector,Unknown)", + "content" : "detectSignificantDuplication(List<ClassMetrics>)", "align" : "left", "path" : null }, { @@ -2397,19 +5707,19 @@ "align" : "right", "path" : null }, { - "content" : "4", + "content" : "8", "align" : "right", "path" : null }, { - "content" : "7", + "content" : "11", "align" : "right", "path" : null }, { - "content" : "8/19/26, 7:20 PM", + "content" : "9/5/26, 1:41 PM", "align" : "right", "path" : null }, { - "content" : "1", + "content" : "15", "align" : "right", "path" : null } ] @@ -2431,7 +5741,7 @@ "align" : "right", "path" : null }, { - "content" : "10", + "content" : "9", "align" : "right", "path" : null }, { @@ -2461,7 +5771,7 @@ "align" : "right", "path" : null }, { - "content" : "11", + "content" : "10", "align" : "right", "path" : null }, { @@ -2482,56 +5792,56 @@ "methodLevel" : true, "problem" : "Method calls a few methods in many classes", "solution" : "Reduce the size of the calling method. Extract methods from the calling method into the target classes.", - "maxPriority" : 34, + "maxPriority" : 35, "chart" : { "canvasId" : "chart_DISPERSED_COUPLING", "bubbles" : [ { "id" : "GraphMetricsCollector.java", "label" : "GraphMetricsCollector.java", "x" : 1, - "y" : 33, + "y" : 32, "r" : 24, "priority" : 1, "effortRank" : 1, - "changePronenessRank" : 33, + "changePronenessRank" : 32, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java" }, { - "id" : "GitLogReader.java", - "label" : "GitLogReader.java", - "x" : 2, - "y" : 31, + "id" : "HierarchyBuilder.java", + "label" : "HierarchyBuilder.java", + "x" : 4, + "y" : 35, "r" : 23, "priority" : 2, - "effortRank" : 2, - "changePronenessRank" : 31, + "effortRank" : 4, + "changePronenessRank" : 35, "color" : "rgba(229, 67, 53, 0.75)", "borderColor" : "rgb(229, 67, 53)", - "path" : "change-proneness-ranker/src/main/java/org/hjug/git/GitLogReader.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/HierarchyBuilder.java" }, { - "id" : "DisharmonyDetector.java", - "label" : "DisharmonyDetector.java", - "x" : 8, - "y" : 34, + "id" : "GitLogReader.java", + "label" : "GitLogReader.java", + "x" : 3, + "y" : 31, "r" : 23, "priority" : 3, - "effortRank" : 8, - "changePronenessRank" : 34, - "color" : "rgba(223, 71, 55, 0.75)", - "borderColor" : "rgb(223, 71, 55)", - "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" + "effortRank" : 3, + "changePronenessRank" : 31, + "color" : "rgba(223, 70, 55, 0.75)", + "borderColor" : "rgb(223, 70, 55)", + "path" : "change-proneness-ranker/src/main/java/org/hjug/git/GitLogReader.java" }, { "id" : "ReportWriter.java", "label" : "ReportWriter.java", - "x" : 4, - "y" : 29, + "x" : 5, + "y" : 30, "r" : 22, "priority" : 4, - "effortRank" : 4, - "changePronenessRank" : 29, - "color" : "rgba(217, 74, 56, 0.75)", - "borderColor" : "rgb(217, 74, 56)", + "effortRank" : 5, + "changePronenessRank" : 30, + "color" : "rgba(218, 74, 56, 0.75)", + "borderColor" : "rgb(218, 74, 56)", "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" }, { "id" : "FeedbackVertexSetSolver.java", @@ -2542,200 +5852,188 @@ "priority" : 5, "effortRank" : 2, "changePronenessRank" : 26, - "color" : "rgba(211, 77, 57, 0.75)", - "borderColor" : "rgb(211, 77, 57)", + "color" : "rgba(212, 77, 57, 0.75)", + "borderColor" : "rgb(212, 77, 57)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/approximate/FeedbackVertexSetSolver.java" }, { "id" : "ReportWriter.java", "label" : "ReportWriter.java", - "x" : 5, - "y" : 29, + "x" : 6, + "y" : 30, "r" : 21, "priority" : 6, - "effortRank" : 5, - "changePronenessRank" : 29, - "color" : "rgba(205, 81, 59, 0.75)", - "borderColor" : "rgb(205, 81, 59)", + "effortRank" : 6, + "changePronenessRank" : 30, + "color" : "rgba(206, 80, 58, 0.75)", + "borderColor" : "rgb(206, 80, 58)", "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" }, { - "id" : "PageRankFAS.java", - "label" : "PageRankFAS.java", - "x" : 9, - "y" : 30, + "id" : "DisharmonyDetector.java", + "label" : "DisharmonyDetector.java", + "x" : 10, + "y" : 33, "r" : 21, "priority" : 7, - "effortRank" : 9, - "changePronenessRank" : 30, - "color" : "rgba(199, 84, 60, 0.75)", - "borderColor" : "rgb(199, 84, 60)", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java" + "effortRank" : 10, + "changePronenessRank" : 33, + "color" : "rgba(200, 83, 60, 0.75)", + "borderColor" : "rgb(200, 83, 60)", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" }, { "id" : "KotlinSourceFileGraphBuilder.java", "label" : "KotlinSourceFileGraphBuilder.java", - "x" : 12, - "y" : 32, + "x" : 14, + "y" : 34, "r" : 20, "priority" : 8, - "effortRank" : 12, - "changePronenessRank" : 32, - "color" : "rgba(193, 87, 61, 0.75)", - "borderColor" : "rgb(193, 87, 61)", + "effortRank" : 14, + "changePronenessRank" : 34, + "color" : "rgba(195, 87, 61, 0.75)", + "borderColor" : "rgb(195, 87, 61)", "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/graphbuilder/KotlinSourceFileGraphBuilder.java" - }, { - "id" : "ReportWriter.java", - "label" : "ReportWriter.java", - "x" : 10, - "y" : 29, - "r" : 20, - "priority" : 9, - "effortRank" : 10, - "changePronenessRank" : 29, - "color" : "rgba(187, 91, 63, 0.75)", - "borderColor" : "rgb(187, 91, 63)", - "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" }, { "id" : "DirectedFeedbackVertexSetSolver.java", "label" : "DirectedFeedbackVertexSetSolver.java", - "x" : 8, + "x" : 6, "y" : 25, - "r" : 19, - "priority" : 10, - "effortRank" : 8, + "r" : 20, + "priority" : 9, + "effortRank" : 6, "changePronenessRank" : 25, - "color" : "rgba(182, 94, 64, 0.75)", - "borderColor" : "rgb(182, 94, 64)", + "color" : "rgba(189, 90, 62, 0.75)", + "borderColor" : "rgb(189, 90, 62)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" }, { - "id" : "MetricsVisitorLogic.java", - "label" : "MetricsVisitorLogic.java", - "x" : 3, - "y" : 19, + "id" : "ReportWriter.java", + "label" : "ReportWriter.java", + "x" : 12, + "y" : 30, "r" : 19, - "priority" : 11, - "effortRank" : 3, - "changePronenessRank" : 19, - "color" : "rgba(176, 97, 65, 0.75)", - "borderColor" : "rgb(176, 97, 65)", - "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" + "priority" : 10, + "effortRank" : 12, + "changePronenessRank" : 30, + "color" : "rgba(183, 93, 64, 0.75)", + "borderColor" : "rgb(183, 93, 64)", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" + }, { + "id" : "CycleRemovalComputer.java", + "label" : "CycleRemovalComputer.java", + "x" : 11, + "y" : 27, + "r" : 19, + "priority" : 11, + "effortRank" : 11, + "changePronenessRank" : 27, + "color" : "rgba(177, 96, 65, 0.75)", + "borderColor" : "rgb(177, 96, 65)", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/CycleRemovalComputer.java" }, { "id" : "DirectedFeedbackVertexSetSolver.java", "label" : "DirectedFeedbackVertexSetSolver.java", - "x" : 9, + "x" : 10, "y" : 25, "r" : 18, "priority" : 12, - "effortRank" : 9, + "effortRank" : 10, "changePronenessRank" : 25, - "color" : "rgba(170, 101, 67, 0.75)", - "borderColor" : "rgb(170, 101, 67)", + "color" : "rgba(172, 100, 66, 0.75)", + "borderColor" : "rgb(172, 100, 66)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" }, { "id" : "TreewidthComputer.java", "label" : "TreewidthComputer.java", "x" : 7, - "y" : 22, - "r" : 17, + "y" : 21, + "r" : 18, "priority" : 13, "effortRank" : 7, - "changePronenessRank" : 22, - "color" : "rgba(164, 104, 68, 0.75)", - "borderColor" : "rgb(164, 104, 68)", + "changePronenessRank" : 21, + "color" : "rgba(166, 103, 68, 0.75)", + "borderColor" : "rgb(166, 103, 68)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" }, { - "id" : "ModulatorComputer.java", - "label" : "ModulatorComputer.java", - "x" : 4, - "y" : 17, + "id" : "DirectedFeedbackVertexSetSolver.java", + "label" : "DirectedFeedbackVertexSetSolver.java", + "x" : 11, + "y" : 25, "r" : 17, "priority" : 14, - "effortRank" : 4, - "changePronenessRank" : 17, - "color" : "rgba(158, 107, 69, 0.75)", - "borderColor" : "rgb(158, 107, 69)", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "effortRank" : 11, + "changePronenessRank" : 25, + "color" : "rgba(160, 106, 69, 0.75)", + "borderColor" : "rgb(160, 106, 69)", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", "x" : 4, "y" : 17, - "r" : 16, + "r" : 17, "priority" : 15, "effortRank" : 4, "changePronenessRank" : 17, - "color" : "rgba(152, 111, 71, 0.75)", - "borderColor" : "rgb(152, 111, 71)", + "color" : "rgba(154, 109, 70, 0.75)", + "borderColor" : "rgb(154, 109, 70)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + }, { + "id" : "MetricsVisitorLogic.java", + "label" : "MetricsVisitorLogic.java", + "x" : 6, + "y" : 18, + "r" : 16, + "priority" : 16, + "effortRank" : 6, + "changePronenessRank" : 18, + "color" : "rgba(149, 113, 71, 0.75)", + "borderColor" : "rgb(149, 113, 71)", + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" }, { "id" : "TreewidthComputer.java", "label" : "TreewidthComputer.java", "x" : 9, - "y" : 22, + "y" : 21, "r" : 16, - "priority" : 16, + "priority" : 17, "effortRank" : 9, - "changePronenessRank" : 22, - "color" : "rgba(146, 114, 72, 0.75)", - "borderColor" : "rgb(146, 114, 72)", + "changePronenessRank" : 21, + "color" : "rgba(143, 116, 73, 0.75)", + "borderColor" : "rgb(143, 116, 73)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", - "x" : 5, + "x" : 6, "y" : 17, "r" : 15, - "priority" : 17, - "effortRank" : 5, + "priority" : 18, + "effortRank" : 6, "changePronenessRank" : 17, - "color" : "rgba(140, 117, 73, 0.75)", - "borderColor" : "rgb(140, 117, 73)", + "color" : "rgba(137, 119, 74, 0.75)", + "borderColor" : "rgb(137, 119, 74)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "TreewidthComputer.java", "label" : "TreewidthComputer.java", "x" : 10, - "y" : 22, - "r" : 15, - "priority" : 18, - "effortRank" : 10, - "changePronenessRank" : 22, - "color" : "rgba(134, 121, 75, 0.75)", - "borderColor" : "rgb(134, 121, 75)", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" - }, { - "id" : "DirectedFeedbackVertexSetSolver.java", - "label" : "DirectedFeedbackVertexSetSolver.java", - "x" : 13, - "y" : 25, + "y" : 21, "r" : 14, "priority" : 19, - "effortRank" : 13, - "changePronenessRank" : 25, - "color" : "rgba(128, 124, 76, 0.75)", - "borderColor" : "rgb(128, 124, 76)", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" - }, { - "id" : "FeedbackVertexSetComputer.java", - "label" : "FeedbackVertexSetComputer.java", - "x" : 4, - "y" : 15, - "r" : 14, - "priority" : 20, - "effortRank" : 4, - "changePronenessRank" : 15, - "color" : "rgba(122, 127, 77, 0.75)", - "borderColor" : "rgb(122, 127, 77)", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/FeedbackVertexSetComputer.java" + "effortRank" : 10, + "changePronenessRank" : 21, + "color" : "rgba(131, 122, 75, 0.75)", + "borderColor" : "rgb(131, 122, 75)", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", - "x" : 6, + "x" : 7, "y" : 17, - "r" : 13, - "priority" : 21, - "effortRank" : 6, + "r" : 14, + "priority" : 20, + "effortRank" : 7, "changePronenessRank" : 17, - "color" : "rgba(116, 131, 79, 0.75)", - "borderColor" : "rgb(116, 131, 79)", + "color" : "rgba(125, 125, 77, 0.75)", + "borderColor" : "rgb(125, 125, 77)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "ModulatorComputer.java", @@ -2743,159 +6041,183 @@ "x" : 7, "y" : 17, "r" : 13, - "priority" : 22, + "priority" : 21, "effortRank" : 7, "changePronenessRank" : 17, - "color" : "rgba(110, 134, 80, 0.75)", - "borderColor" : "rgb(110, 134, 80)", + "color" : "rgba(120, 129, 78, 0.75)", + "borderColor" : "rgb(120, 129, 78)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + }, { + "id" : "DirectedFeedbackVertexSetSolver.java", + "label" : "DirectedFeedbackVertexSetSolver.java", + "x" : 15, + "y" : 25, + "r" : 13, + "priority" : 22, + "effortRank" : 15, + "changePronenessRank" : 25, + "color" : "rgba(114, 132, 79, 0.75)", + "borderColor" : "rgb(114, 132, 79)", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" + }, { + "id" : "FeedbackVertexSetComputer.java", + "label" : "FeedbackVertexSetComputer.java", + "x" : 6, + "y" : 15, + "r" : 12, + "priority" : 23, + "effortRank" : 6, + "changePronenessRank" : 15, + "color" : "rgba(108, 135, 80, 0.75)", + "borderColor" : "rgb(108, 135, 80)", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/FeedbackVertexSetComputer.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", "x" : 8, "y" : 17, "r" : 12, - "priority" : 23, + "priority" : 24, "effortRank" : 8, "changePronenessRank" : 17, - "color" : "rgba(104, 137, 81, 0.75)", - "borderColor" : "rgb(104, 137, 81)", + "color" : "rgba(102, 138, 82, 0.75)", + "borderColor" : "rgb(102, 138, 82)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", - "x" : 8, + "x" : 10, "y" : 17, "r" : 11, - "priority" : 24, - "effortRank" : 8, + "priority" : 25, + "effortRank" : 10, "changePronenessRank" : 17, - "color" : "rgba(98, 141, 83, 0.75)", - "borderColor" : "rgb(98, 141, 83)", + "color" : "rgba(97, 142, 83, 0.75)", + "borderColor" : "rgb(97, 142, 83)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { - "id" : "CycleRemovalComputer.java", - "label" : "CycleRemovalComputer.java", - "x" : 9, - "y" : 18, + "id" : "ModulatorComputer.java", + "label" : "ModulatorComputer.java", + "x" : 10, + "y" : 17, "r" : 11, - "priority" : 25, - "effortRank" : 9, - "changePronenessRank" : 18, - "color" : "rgba(92, 144, 84, 0.75)", - "borderColor" : "rgb(92, 144, 84)", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/CycleRemovalComputer.java" - }, { - "id" : "MinimumFeedbackArcSetSolver.java", - "label" : "MinimumFeedbackArcSetSolver.java", - "x" : 4, - "y" : 10, - "r" : 10, "priority" : 26, - "effortRank" : 4, - "changePronenessRank" : 10, - "color" : "rgba(87, 147, 85, 0.75)", - "borderColor" : "rgb(87, 147, 85)", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" + "effortRank" : 10, + "changePronenessRank" : 17, + "color" : "rgba(91, 145, 84, 0.75)", + "borderColor" : "rgb(91, 145, 84)", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "MinimumFeedbackArcSetSolver.java", "label" : "MinimumFeedbackArcSetSolver.java", - "x" : 4, - "y" : 10, + "x" : 5, + "y" : 11, "r" : 10, "priority" : 27, - "effortRank" : 4, - "changePronenessRank" : 10, - "color" : "rgba(81, 151, 87, 0.75)", - "borderColor" : "rgb(81, 151, 87)", + "effortRank" : 5, + "changePronenessRank" : 11, + "color" : "rgba(85, 148, 86, 0.75)", + "borderColor" : "rgb(85, 148, 86)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" }, { "id" : "LineDigraph.java", "label" : "LineDigraph.java", - "x" : 8, + "x" : 10, "y" : 14, - "r" : 9, + "r" : 10, "priority" : 28, - "effortRank" : 8, + "effortRank" : 10, "changePronenessRank" : 14, - "color" : "rgba(75, 154, 88, 0.75)", - "borderColor" : "rgb(75, 154, 88)", + "color" : "rgba(79, 151, 87, 0.75)", + "borderColor" : "rgb(79, 151, 87)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/LineDigraph.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", - "x" : 11, + "x" : 13, "y" : 17, "r" : 9, "priority" : 29, - "effortRank" : 11, + "effortRank" : 13, "changePronenessRank" : 17, - "color" : "rgba(69, 157, 89, 0.75)", - "borderColor" : "rgb(69, 157, 89)", + "color" : "rgba(74, 155, 88, 0.75)", + "borderColor" : "rgb(74, 155, 88)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + }, { + "id" : "MinimumFeedbackArcSetSolver.java", + "label" : "MinimumFeedbackArcSetSolver.java", + "x" : 8, + "y" : 11, + "r" : 9, + "priority" : 30, + "effortRank" : 8, + "changePronenessRank" : 11, + "color" : "rgba(68, 158, 90, 0.75)", + "borderColor" : "rgb(68, 158, 90)", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" }, { "id" : "FeedbackVertexSetComputer.java", "label" : "FeedbackVertexSetComputer.java", - "x" : 10, + "x" : 12, "y" : 15, "r" : 8, - "priority" : 30, - "effortRank" : 10, + "priority" : 31, + "effortRank" : 12, "changePronenessRank" : 15, - "color" : "rgba(63, 161, 91, 0.75)", - "borderColor" : "rgb(63, 161, 91)", + "color" : "rgba(62, 161, 91, 0.75)", + "borderColor" : "rgb(62, 161, 91)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/FeedbackVertexSetComputer.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", - "x" : 12, + "x" : 14, "y" : 17, "r" : 8, - "priority" : 31, - "effortRank" : 12, + "priority" : 32, + "effortRank" : 14, "changePronenessRank" : 17, - "color" : "rgba(57, 164, 92, 0.75)", - "borderColor" : "rgb(57, 164, 92)", + "color" : "rgba(56, 164, 92, 0.75)", + "borderColor" : "rgb(56, 164, 92)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "MinimumFeedbackArcSetSolver.java", "label" : "MinimumFeedbackArcSetSolver.java", - "x" : 7, - "y" : 10, + "x" : 9, + "y" : 11, "r" : 7, - "priority" : 32, - "effortRank" : 7, - "changePronenessRank" : 10, - "color" : "rgba(51, 167, 93, 0.75)", - "borderColor" : "rgb(51, 167, 93)", + "priority" : 33, + "effortRank" : 9, + "changePronenessRank" : 11, + "color" : "rgba(51, 168, 93, 0.75)", + "borderColor" : "rgb(51, 168, 93)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" }, { "id" : "FeedbackArcSetSolver.java", "label" : "FeedbackArcSetSolver.java", - "x" : 4, - "y" : 3, + "x" : 6, + "y" : 4, "r" : 7, - "priority" : 33, - "effortRank" : 4, - "changePronenessRank" : 3, + "priority" : 34, + "effortRank" : 6, + "changePronenessRank" : 4, "color" : "rgba(45, 171, 95, 0.75)", "borderColor" : "rgb(45, 171, 95)", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/approximate/FeedbackArcSetSolver.java" }, { "id" : "AttributeHandlerAndSorter.java", "label" : "AttributeHandlerAndSorter.java", - "x" : 7, + "x" : 8, "y" : 1, "r" : 6, - "priority" : 34, - "effortRank" : 7, + "priority" : 35, + "effortRank" : 8, "changePronenessRank" : 1, "color" : "rgba(39, 174, 96, 0.75)", "borderColor" : "rgb(39, 174, 96)", "path" : "test-resources/src/main/resources/AttributeHandlerAndSorter.java" } ], - "yaxisLabel" : "Relative churn (impact)", - "xaxisLabel" : "Effort to refactor" + "xaxisLabel" : "Effort to refactor", + "yaxisLabel" : "Relative churn (impact)" }, "table" : { "headers" : [ "Class", "Method", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], @@ -2913,7 +6235,7 @@ "align" : "right", "path" : null }, { - "content" : "33", + "content" : "32", "align" : "right", "path" : null }, { @@ -2921,21 +6243,21 @@ "align" : "right", "path" : null }, { - "content" : "9/24/26, 8:03 AM", + "content" : "10/17/26, 8:36 AM", "align" : "right", "path" : null }, { - "content" : "13", + "content" : "15", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "GitLogReader.java", + "content" : "HierarchyBuilder.java", "align" : "left", - "path" : "change-proneness-ranker/src/main/java/org/hjug/git/GitLogReader.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/HierarchyBuilder.java" }, { - "content" : "captureChangeCountByCommitTimestamp()", + "content" : "buildClassLevelHierarchy(Unknown,CodebaseGraphDTO,Set<VertexInfo>,Set<VertexInfo>,Set<{undefined}>,Set<String>,Set<{undefined}>,boolean)", "align" : "left", "path" : null }, { @@ -2943,29 +6265,29 @@ "align" : "right", "path" : null }, { - "content" : "31", + "content" : "35", "align" : "right", "path" : null }, { - "content" : "2", + "content" : "4", "align" : "right", "path" : null }, { - "content" : "9/14/26, 1:00 PM", + "content" : "10/20/26, 5:35 PM", "align" : "right", "path" : null }, { - "content" : "21", + "content" : "1", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "DisharmonyDetector.java", + "content" : "GitLogReader.java", "align" : "left", - "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" + "path" : "change-proneness-ranker/src/main/java/org/hjug/git/GitLogReader.java" }, { - "content" : "detectFeatureEnvy(List<ClassMetrics>)", + "content" : "captureChangeCountByCommitTimestamp()", "align" : "left", "path" : null }, { @@ -2973,19 +6295,19 @@ "align" : "right", "path" : null }, { - "content" : "34", + "content" : "31", "align" : "right", "path" : null }, { - "content" : "8", + "content" : "3", "align" : "right", "path" : null }, { - "content" : "9/5/26, 1:41 PM", + "content" : "9/14/26, 1:00 PM", "align" : "right", "path" : null }, { - "content" : "15", + "content" : "21", "align" : "right", "path" : null } ] @@ -2995,7 +6317,7 @@ "align" : "left", "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" }, { - "content" : "openSecurePath()", + "content" : "writeAtomically(Path,String)", "align" : "left", "path" : null }, { @@ -3003,11 +6325,11 @@ "align" : "right", "path" : null }, { - "content" : "29", + "content" : "30", "align" : "right", "path" : null }, { - "content" : "4", + "content" : "5", "align" : "right", "path" : null }, { @@ -3055,7 +6377,7 @@ "align" : "left", "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" }, { - "content" : "writeAtomically(Path,String)", + "content" : "openSecurePath()", "align" : "left", "path" : null }, { @@ -3063,11 +6385,11 @@ "align" : "right", "path" : null }, { - "content" : "29", + "content" : "30", "align" : "right", "path" : null }, { - "content" : "5", + "content" : "6", "align" : "right", "path" : null }, { @@ -3081,11 +6403,11 @@ } ] }, { "cells" : [ { - "content" : "PageRankFAS.java", + "content" : "DisharmonyDetector.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java" + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" }, { - "content" : "createLineDigraphEdgesDFS(Unknown,LineDigraph<V,E>,Map<E,LineVertex<V,E>>,V,LineVertex<V,E>,Set<V>)", + "content" : "detectFeatureEnvy(List<ClassMetrics>)", "align" : "left", "path" : null }, { @@ -3093,19 +6415,19 @@ "align" : "right", "path" : null }, { - "content" : "30", + "content" : "33", "align" : "right", "path" : null }, { - "content" : "9", + "content" : "10", "align" : "right", "path" : null }, { - "content" : "10/4/26, 5:04 PM", + "content" : "9/5/26, 1:41 PM", "align" : "right", "path" : null }, { - "content" : "6", + "content" : "15", "align" : "right", "path" : null } ] @@ -3123,29 +6445,29 @@ "align" : "right", "path" : null }, { - "content" : "32", + "content" : "34", "align" : "right", "path" : null }, { - "content" : "12", + "content" : "14", "align" : "right", "path" : null }, { - "content" : "9/5/26, 1:25 PM", + "content" : "10/17/26, 8:36 AM", "align" : "right", "path" : null }, { - "content" : "8", + "content" : "10", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "ReportWriter.java", + "content" : "DirectedFeedbackVertexSetSolver.java", "align" : "left", - "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" }, { - "content" : "writeAtomicallySecure(SecureDirectoryStream<Path>,Path,String)", + "content" : "computeMinimumVertexCut(V,Set<V>,int)", "align" : "left", "path" : null }, { @@ -3153,29 +6475,29 @@ "align" : "right", "path" : null }, { - "content" : "29", + "content" : "25", "align" : "right", "path" : null }, { - "content" : "10", + "content" : "6", "align" : "right", "path" : null }, { - "content" : "9/5/26, 8:03 AM", + "content" : "8/26/26, 7:48 PM", "align" : "right", "path" : null }, { - "content" : "10", + "content" : "3", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "DirectedFeedbackVertexSetSolver.java", + "content" : "ReportWriter.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" + "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" }, { - "content" : "createMinimalBypass(V,Set<V>,Set<E>)", + "content" : "writeAtomicallySecure(SecureDirectoryStream<Path>,Path,String)", "align" : "left", "path" : null }, { @@ -3183,29 +6505,29 @@ "align" : "right", "path" : null }, { - "content" : "25", + "content" : "30", "align" : "right", "path" : null }, { - "content" : "8", + "content" : "12", "align" : "right", "path" : null }, { - "content" : "8/26/26, 7:48 PM", + "content" : "9/5/26, 8:03 AM", "align" : "right", "path" : null }, { - "content" : "3", + "content" : "10", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "MetricsVisitorLogic.java", + "content" : "CycleRemovalComputer.java", "align" : "left", - "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/CycleRemovalComputer.java" }, { - "content" : "handleMethodInvocation(MetricsVisitorState,GraphMetricsCollector,Unknown)", + "content" : "computeCycleRemovalInformation(Unknown)", "align" : "left", "path" : null }, { @@ -3213,19 +6535,19 @@ "align" : "right", "path" : null }, { - "content" : "19", + "content" : "27", "align" : "right", "path" : null }, { - "content" : "3", + "content" : "11", "align" : "right", "path" : null }, { - "content" : "8/19/26, 7:20 PM", + "content" : "10/17/26, 8:36 AM", "align" : "right", "path" : null }, { - "content" : "1", + "content" : "3", "align" : "right", "path" : null } ] @@ -3235,7 +6557,7 @@ "align" : "left", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" }, { - "content" : "findBypassChain(V,Set<V>)", + "content" : "createMinimalBypass(V,Set<V>,Set<E>)", "align" : "left", "path" : null }, { @@ -3247,7 +6569,7 @@ "align" : "right", "path" : null }, { - "content" : "9", + "content" : "10", "align" : "right", "path" : null }, { @@ -3265,7 +6587,7 @@ "align" : "left", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" }, { - "content" : "computeEta(Unknown,Set<V>)", + "content" : "minDegreeEliminationTreewidth(Unknown)", "align" : "left", "path" : null }, { @@ -3273,7 +6595,7 @@ "align" : "right", "path" : null }, { - "content" : "22", + "content" : "21", "align" : "right", "path" : null }, { @@ -3291,11 +6613,11 @@ } ] }, { "cells" : [ { - "content" : "ModulatorComputer.java", + "content" : "DirectedFeedbackVertexSetSolver.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" }, { - "content" : "computeBetweennessCentrality(Unknown)", + "content" : "findBypassChain(V,Set<V>)", "align" : "left", "path" : null }, { @@ -3303,19 +6625,19 @@ "align" : "right", "path" : null }, { - "content" : "17", + "content" : "25", "align" : "right", "path" : null }, { - "content" : "4", + "content" : "11", "align" : "right", "path" : null }, { - "content" : "12/18/25, 11:00 AM", + "content" : "8/26/26, 7:48 PM", "align" : "right", "path" : null }, { - "content" : "1", + "content" : "3", "align" : "right", "path" : null } ] @@ -3325,7 +6647,7 @@ "align" : "left", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { - "content" : "computeGreedyDegreeModulator(Unknown,int,int)", + "content" : "computeBetweennessCentrality(Unknown)", "align" : "left", "path" : null }, { @@ -3351,11 +6673,11 @@ } ] }, { "cells" : [ { - "content" : "TreewidthComputer.java", + "content" : "MetricsVisitorLogic.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" + "path" : "codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" }, { - "content" : "greedyTriangulationTreewidth(Unknown)", + "content" : "handleMethodInvocation(MetricsVisitorState,GraphMetricsCollector,Unknown)", "align" : "left", "path" : null }, { @@ -3363,29 +6685,29 @@ "align" : "right", "path" : null }, { - "content" : "22", + "content" : "18", "align" : "right", "path" : null }, { - "content" : "9", + "content" : "6", "align" : "right", "path" : null }, { - "content" : "7/12/26, 3:24 PM", + "content" : "8/19/26, 7:20 PM", "align" : "right", "path" : null }, { - "content" : "2", + "content" : "1", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "ModulatorComputer.java", + "content" : "TreewidthComputer.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" }, { - "content" : "computeFeedbackVertexSetModulator(Unknown,int,int)", + "content" : "computeEta(Unknown,Set<V>)", "align" : "left", "path" : null }, { @@ -3393,29 +6715,29 @@ "align" : "right", "path" : null }, { - "content" : "17", + "content" : "21", "align" : "right", "path" : null }, { - "content" : "5", + "content" : "9", "align" : "right", "path" : null }, { - "content" : "12/18/25, 11:00 AM", + "content" : "7/12/26, 3:24 PM", "align" : "right", "path" : null }, { - "content" : "1", + "content" : "2", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "TreewidthComputer.java", + "content" : "ModulatorComputer.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { - "content" : "fillInHeuristicTreewidth(Unknown)", + "content" : "computeGreedyDegreeModulator(Unknown,int,int)", "align" : "left", "path" : null }, { @@ -3423,29 +6745,29 @@ "align" : "right", "path" : null }, { - "content" : "22", + "content" : "17", "align" : "right", "path" : null }, { - "content" : "10", + "content" : "6", "align" : "right", "path" : null }, { - "content" : "7/12/26, 3:24 PM", + "content" : "12/18/25, 11:00 AM", "align" : "right", "path" : null }, { - "content" : "2", + "content" : "1", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "DirectedFeedbackVertexSetSolver.java", + "content" : "TreewidthComputer.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" }, { - "content" : "addBypassEdges(V,Set<V>)", + "content" : "fillInHeuristicTreewidth(Unknown)", "align" : "left", "path" : null }, { @@ -3453,29 +6775,29 @@ "align" : "right", "path" : null }, { - "content" : "25", + "content" : "21", "align" : "right", "path" : null }, { - "content" : "13", + "content" : "10", "align" : "right", "path" : null }, { - "content" : "8/26/26, 7:48 PM", + "content" : "7/12/26, 3:24 PM", "align" : "right", "path" : null }, { - "content" : "3", + "content" : "2", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "FeedbackVertexSetComputer.java", + "content" : "ModulatorComputer.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/FeedbackVertexSetComputer.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { - "content" : "stronglyConnectedComponentsBasedFVS(Unknown)", + "content" : "computeFeedbackVertexSetModulator(Unknown,int,int)", "align" : "left", "path" : null }, { @@ -3483,11 +6805,11 @@ "align" : "right", "path" : null }, { - "content" : "15", + "content" : "17", "align" : "right", "path" : null }, { - "content" : "4", + "content" : "7", "align" : "right", "path" : null }, { @@ -3517,7 +6839,7 @@ "align" : "right", "path" : null }, { - "content" : "6", + "content" : "7", "align" : "right", "path" : null }, { @@ -3531,11 +6853,11 @@ } ] }, { "cells" : [ { - "content" : "ModulatorComputer.java", + "content" : "DirectedFeedbackVertexSetSolver.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" }, { - "content" : "originalComputeBetweennessCentrality(Unknown)", + "content" : "addBypassEdges(V,Set<V>)", "align" : "left", "path" : null }, { @@ -3543,29 +6865,29 @@ "align" : "right", "path" : null }, { - "content" : "17", + "content" : "25", "align" : "right", "path" : null }, { - "content" : "7", + "content" : "15", "align" : "right", "path" : null }, { - "content" : "12/18/25, 11:00 AM", + "content" : "8/26/26, 7:48 PM", "align" : "right", "path" : null }, { - "content" : "1", + "content" : "3", "align" : "right", "path" : null } ] }, { "cells" : [ { - "content" : "ModulatorComputer.java", + "content" : "FeedbackVertexSetComputer.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/FeedbackVertexSetComputer.java" }, { - "content" : "computeSingleSourceBetweennessContributions(Unknown,V)", + "content" : "stronglyConnectedComponentsBasedFVS(Unknown)", "align" : "left", "path" : null }, { @@ -3573,11 +6895,11 @@ "align" : "right", "path" : null }, { - "content" : "17", + "content" : "15", "align" : "right", "path" : null }, { - "content" : "8", + "content" : "6", "align" : "right", "path" : null }, { @@ -3595,7 +6917,7 @@ "align" : "left", "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { - "content" : "computeBetweennessCentralityAdaptive(Unknown)", + "content" : "originalComputeBetweennessCentrality(Unknown)", "align" : "left", "path" : null }, { @@ -3621,11 +6943,11 @@ } ] }, { "cells" : [ { - "content" : "CycleRemovalComputer.java", + "content" : "ModulatorComputer.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/CycleRemovalComputer.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { - "content" : "computeCycleRemovalInformation(Unknown)", + "content" : "computeSingleSourceBetweennessContributions(Unknown,V)", "align" : "left", "path" : null }, { @@ -3633,15 +6955,15 @@ "align" : "right", "path" : null }, { - "content" : "18", + "content" : "17", "align" : "right", "path" : null }, { - "content" : "9", + "content" : "10", "align" : "right", "path" : null }, { - "content" : "6/16/26, 7:10 PM", + "content" : "12/18/25, 11:00 AM", "align" : "right", "path" : null }, { @@ -3651,11 +6973,11 @@ } ] }, { "cells" : [ { - "content" : "MinimumFeedbackArcSetSolver.java", + "content" : "ModulatorComputer.java", "align" : "left", - "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { - "content" : "findShortestPath(Unknown,V)", + "content" : "computeBetweennessCentralityAdaptive(Unknown)", "align" : "left", "path" : null }, { @@ -3663,11 +6985,11 @@ "align" : "right", "path" : null }, { - "content" : "10", + "content" : "17", "align" : "right", "path" : null }, { - "content" : "4", + "content" : "10", "align" : "right", "path" : null }, { @@ -3693,11 +7015,11 @@ "align" : "right", "path" : null }, { - "content" : "10", + "content" : "11", "align" : "right", "path" : null }, { - "content" : "4", + "content" : "5", "align" : "right", "path" : null }, { @@ -3727,7 +7049,7 @@ "align" : "right", "path" : null }, { - "content" : "8", + "content" : "10", "align" : "right", "path" : null }, { @@ -3756,10 +7078,40 @@ "content" : "17", "align" : "right", "path" : null + }, { + "content" : "13", + "align" : "right", + "path" : null + }, { + "content" : "12/18/25, 11:00 AM", + "align" : "right", + "path" : null + }, { + "content" : "1", + "align" : "right", + "path" : null + } ] + }, { + "cells" : [ { + "content" : "MinimumFeedbackArcSetSolver.java", + "align" : "left", + "path" : "graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" + }, { + "content" : "findShortestPath(Unknown,V)", + "align" : "left", + "path" : null + }, { + "content" : "30", + "align" : "right", + "path" : null }, { "content" : "11", "align" : "right", "path" : null + }, { + "content" : "8", + "align" : "right", + "path" : null }, { "content" : "12/18/25, 11:00 AM", "align" : "right", @@ -3779,7 +7131,7 @@ "align" : "left", "path" : null }, { - "content" : "30", + "content" : "31", "align" : "right", "path" : null }, { @@ -3787,7 +7139,7 @@ "align" : "right", "path" : null }, { - "content" : "10", + "content" : "12", "align" : "right", "path" : null }, { @@ -3809,7 +7161,7 @@ "align" : "left", "path" : null }, { - "content" : "31", + "content" : "32", "align" : "right", "path" : null }, { @@ -3817,7 +7169,7 @@ "align" : "right", "path" : null }, { - "content" : "12", + "content" : "14", "align" : "right", "path" : null }, { @@ -3839,15 +7191,15 @@ "align" : "left", "path" : null }, { - "content" : "32", + "content" : "33", "align" : "right", "path" : null }, { - "content" : "10", + "content" : "11", "align" : "right", "path" : null }, { - "content" : "7", + "content" : "9", "align" : "right", "path" : null }, { @@ -3869,15 +7221,15 @@ "align" : "left", "path" : null }, { - "content" : "33", + "content" : "34", "align" : "right", "path" : null }, { - "content" : "3", + "content" : "4", "align" : "right", "path" : null }, { - "content" : "4", + "content" : "6", "align" : "right", "path" : null }, { @@ -3899,7 +7251,7 @@ "align" : "left", "path" : null }, { - "content" : "34", + "content" : "35", "align" : "right", "path" : null }, { @@ -3907,7 +7259,7 @@ "align" : "right", "path" : null }, { - "content" : "7", + "content" : "8", "align" : "right", "path" : null }, { @@ -3929,6 +7281,11 @@ "priority" : 1, "classCount" : 4, "relationshipCount" : 7 + }, { + "cycleName" : "HierarchyBuilder", + "priority" : 2, + "classCount" : 3, + "relationshipCount" : 4 } ], "largestCycle" : { "hasCycleMap" : true, @@ -3936,13 +7293,89 @@ "cycleIdentifier" : "graph_ReportWriter_SecureDirectoryOps_g0qpeh", "classCount" : 4, "relationshipCount" : 7, - "dot" : "strict digraph G {\nReportWriter -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"3\" weight = \"3\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl [ label = \"1\" weight = \"1\" color = \"red\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps [ label = \"1\" weight = \"1\" color = \"red\" ];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps -> ReportWriter [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl -> ReportWriter [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label=\"ReportWriter$SecureDirectoryOps\"];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps [ label=\"ReportWriter$FallbackDirectoryOps\"];\nReportWriter [ color=red style=filled];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl [ label=\"ReportWriter$SecureDirectoryOpsImpl\"];\n}", + "hierarchy" : { + "packages" : [ { + "name" : "org.hjug.refactorfirst.report", + "id" : "cluster_864d6940ac14438961598d5a", + "nodeId" : null, + "renderAsNode" : false, + "needsBreakUp" : false, + "path" : "", + "children" : [ ], + "classes" : [ { + "fqn" : "org.hjug.refactorfirst.report.ReportWriter", + "id" : "ReportWriter", + "label" : "ReportWriter", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", + "markedForRemoval" : true + }, { + "fqn" : "org.hjug.refactorfirst.report.ReportWriter$FallbackDirectoryOps", + "id" : "org_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps", + "label" : "ReportWriter$FallbackDirectoryOps", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.ReportWriter$SecureDirectoryOps", + "id" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps", + "label" : "ReportWriter$SecureDirectoryOps", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", + "markedForRemoval" : false + }, { + "fqn" : "org.hjug.refactorfirst.report.ReportWriter$SecureDirectoryOpsImpl", + "id" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl", + "label" : "ReportWriter$SecureDirectoryOpsImpl", + "path" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", + "markedForRemoval" : false + } ] + } ], + "edges" : [ { + "source" : "ReportWriter", + "target" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps", + "weight" : 3, + "markedForRemoval" : false + }, { + "source" : "org_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps", + "target" : "ReportWriter", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "org_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps", + "target" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps", + "target" : "org_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps", + "weight" : 1, + "markedForRemoval" : true + }, { + "source" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps", + "target" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl", + "weight" : 1, + "markedForRemoval" : true + }, { + "source" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl", + "target" : "ReportWriter", + "weight" : 1, + "markedForRemoval" : false + }, { + "source" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl", + "target" : "org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps", + "weight" : 1, + "markedForRemoval" : false + } ] + }, "dotThresholdExceeded" : false, "breakdown" : [ { "className" : "ReportWriter$SecureDirectoryOps", "classPath" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", "marked" : false, "edgesHtml" : "ReportWriter$SecureDirectoryOps → ReportWriter$SecureDirectoryOpsImpl : 1*
\nReportWriter$SecureDirectoryOps → ReportWriter$FallbackDirectoryOps : 1*
\n" + }, { + "className" : "ReportWriter$SecureDirectoryOpsImpl", + "classPath" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", + "marked" : false, + "edgesHtml" : "ReportWriter$SecureDirectoryOpsImpl → ReportWriter$SecureDirectoryOps : 1
\nReportWriter$SecureDirectoryOpsImpl → ReportWriter : 1
\n" }, { "className" : "ReportWriter$FallbackDirectoryOps", "classPath" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", @@ -3953,11 +7386,6 @@ "classPath" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", "marked" : true, "edgesHtml" : "ReportWriter → ReportWriter$SecureDirectoryOps : 3
\n" - }, { - "className" : "ReportWriter$SecureDirectoryOpsImpl", - "classPath" : "report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java", - "marked" : false, - "edgesHtml" : "ReportWriter$SecureDirectoryOpsImpl → ReportWriter$SecureDirectoryOps : 1
\nReportWriter$SecureDirectoryOpsImpl → ReportWriter : 1
\n" } ] } } diff --git a/AGENTS.md b/AGENTS.md index ce9e6249..4d79d8c6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,8 +14,104 @@ - Central DTO: `CodebaseGraphDTO` (JGraphT graphs + disharmony lists + metrics) - CLI entry point: `org.hjug.refactorfirst.Main` → `ReportCommand` - Fat jar location: `cli/target/cli-.jar` -- **Anonymous/synthetic classes are first-class graph members.** Java `Outer$N`/`Outer$` (anonymous/synthetic inner classes) and the Kotlin literal `""` FQN are **not** sieved out by `GraphDependencyCollector`; they genuinely participate in cycles and can harbour antipatterns, so they are vertices in the class graph and rendered with `$` as the enclosing-class separator. `GraphDependencyCollector` keeps only the `from == to` self-edge guard, plus a degenerate-package guard so a packageless `""` source never creates an `""` package-graph vertex. **Sink-only** anonymous/synthetic vertices (those with no outgoing edges) are suppressed only at render time in `HtmlReport.isSinkAnonymousOrSyntheticVertex` to keep the Class/Cycle Map DOT graph readable; active ones still render. -- **Anonymous DOT node ids are source-file derived.** OpenRewrite attributes a Kotlin anonymous object / function-literal type with {@code ""} as the trailing simple-name segment of its FQN: standalone ({@code ""}) or, in real graphs (e.g. FXGL), prefixed by the enclosing class/package ({@code "dev.DeveloperWASDControl."}). {@code HtmlReport.isAnonymousFqn(vertex)} detects a vertex when its trailing segment starts with {@code <}. {@code HtmlReport.renderSafeNodeId(vertex, codebaseGraphDTO)} then derives the enclosing owner from the vertex's mapped source-file path in {@code CodebaseGraphDTO.classToSourceFilePathMapping} (file base name without extension, e.g. {@code DeveloperWASDControl.kt} -> {@code DeveloperWASDControl}). The DOT node id renders as {@code DeveloperWASDControl_anonymous} and the human-readable label as {@code DeveloperWASDControl\$anonymous} ({@code $} escaped as {@code \$} for DOT). When no source path is mapped (or DTO is null) it degrades to the reversible {@code lt_}/{@code _gt} {@code <}/{@code >} encoding. The renderer is responsible for DOT/HTML-safe encoding of the literal {@code ""} FQN ({@code <}/{@code >} are illegal in Graphviz node ids; {@code <}/{@code >} escaping in HTML table labels). +- **Anonymous/synthetic classes are first-class graph members.** Java `Outer$N`/`Outer$` (anonymous/synthetic inner classes) and the Kotlin literal `""` FQN are **not** sieved out by `GraphDependencyCollector`; they genuinely participate in cycles and can harbour antipatterns, so they are vertices in the class graph and rendered with `$` as the enclosing-class separator. `GraphDependencyCollector` keeps only the `from == to` self-edge guard, plus a degenerate-package guard so an anonymous source never creates an `""` package-graph vertex: the package of a Kotlin anonymous FQN derives from its **enclosing class** (`dev.Owner.` → `dev`, and a packageless `Owner`/bare `""` → no package edge), never a pseudo-package named after the owner — this keeps the package graph's names aligned with the class hierarchy's package derivation so the break-up lists in the Class and Package graphs match. **Sink-only** anonymous/synthetic vertices (those with no outgoing edges) are suppressed at hierarchy-build time in `HierarchyBuilder` (via the same `HtmlReport.isSinkAnonymousOrSyntheticVertex` static) to keep the Class/Cycle Map DOT graph readable; active ones still render, and edges touching a suppressed vertex are dropped with it. +- **Anonymous DOT node ids are source-file derived.** OpenRewrite attributes a Kotlin anonymous object / function-literal type with {@code ""} as the trailing simple-name segment of its FQN: standalone ({@code ""}) or, in real graphs (e.g. FXGL), prefixed by the enclosing class/package ({@code "dev.DeveloperWASDControl."}). {@code HtmlReport.isAnonymousFqn(vertex)} detects a vertex when its trailing segment starts with {@code <}. `HierarchyBuilder` resolves the id and label once, into the {@code ClassNodeDTO} (calling {@code HtmlReport.renderSafeNodeId(vertex, classGraph, codebaseGraphDTO)} / {@code anonymousOwnerLabel} / {@code getClassName}), deriving the enclosing owner from the vertex's mapped source-file path in {@code CodebaseGraphDTO.classToSourceFilePathMapping} (file base name without extension, e.g. {@code DeveloperWASDControl.kt} -> {@code DeveloperWASDControl}). The DOT node id renders as {@code DeveloperWASDControl_anonymous} and the human-readable label as {@code DeveloperWASDControl$anonymous}; labels are carried unescaped in the DTO and DOT-quoted at emission (the JS-template-literal wrapper additionally escapes {@code $} for the inline HTML report). When no source path is mapped (or DTO is null) it degrades to the reversible {@code lt_}/{@code _gt} {@code <}/{@code >} encoding. Note the render path (the 3-arg `renderSafeNodeId`) emits no hash discriminator, so same-named source files in different packages can collide — a pre-existing wart; the 2-arg overload's hash discriminator is not used for graphs. + +## Nested graph hierarchy (HierarchyDTO + DOT synthesis) + +Every generated graph (Class Map, Cycle Map, Package Map) renders as a nested +package/class hierarchy. The pipeline is single-sourced: + +`VertexInfo` graphs → `HierarchyBuilder` → `HierarchyDTO` → DOT emission. + +- **`refactor-first.json` carries the hierarchy, not raw DOT** (0.11.0 breaking + change): `classMap.dot`, `packageMap.dot` and + `classCycles.largestCycle.dot` are gone, replaced by `.hierarchy` objects + (`packages` tree + `edges` referencing pre-resolved node ids). Counts and + gates (`dotThreshold`, `dotThresholdExceeded`, `hasEdges`) keep their names. + There is no schema version and no legacy `.dot` fallback — reports published + with older versions lose their graphs on hierarchy-only viewers until + regenerated. +- **`HierarchyBuilder`** (report module) builds the three hierarchies: + `buildClassHierarchy` (endpoints of every class edge), `buildCycleHierarchy` + (a cycle's members, ids still resolved against the FULL class graph), and + `buildPackageHierarchy` (the package-map hierarchy **data**: relationship + participants and break-up packages join the tree with their node ids, + source paths, and `renderAsNode` leaf flags — rendering is the DOT + builders' job, and `buildPackageDot` draws every participating package as + a flat `shape=ellipse` node, never as rectangles under ancestor clusters). + Nested `$`/Kotlin `` classes resolve to the owning package; + packageless classes land in the synthetic `(default package)` bucket. + Roots/children/classes/edges are sorted for determinism and single-child + ancestor chains collapse into their deepest package (branching ancestors + and content keep their boxes). +- **Ids/labels are resolved once, into the DTO** (`ClassNodeDTO.id`/`label`, + `PackageNodeDTO.id`/`nodeId`) and carried unescaped; renderers escape at + emission. Class ids reuse the `HtmlReport.renderSafeNodeId` rules, package + node ids are `package_` (`renderSafePackageNodeId`), cluster ids are + `cluster_` (`HierarchyBuilder.clusterId`). +- **`NestedDotBuilder`** emits the nested DOT in two modes. + *Class/cycle maps* (`buildNestedDot(hierarchy, repoUrl, includeHyperlinks)`): + packages as labelled `subgraph cluster_*` blocks (clusters BEFORE edges — in + DOT a node belongs to the cluster where it is first defined), classes as + `shape=ellipse` nodes. Removal colors: classes/edges keep + `color=red style=filled`; flagged clusters fill pink. Every cluster + declares an explicit fill — pink when flagged, `fillcolor=white` otherwise + — because vizdom propagates a styled cluster's fill to its nested cluster + rects; the explicit white keeps child packages of a pink cluster on their + normal fill. + *Package map* (`buildPackageDot(hierarchy)`): the flat relationship graph, + matching the main-branch package map — every package that participates in + at least one relationship (or was selected for removal to break cycles) + renders once as a `shape=ellipse` node carrying its name, and the edges + carry only the relationship weights. Break-up packages fill red + (`color=red style=filled`), removal relationships render red, and the + package map renders through **vizdom** like the class and cycle maps (no + separate engine). Every graph's nodes are **hyperlinked**: class nodes link + to their source files and package nodes to their source directories via + `URL="" target="_blank"` (http(s)-gated — payloads are + untrusted on the page/viewer). vizdom honors node `URL` but drops + `target`, so every render site restores it with a post-render + `svg.replace(/ 0` and drop them and any edge touching + them, while keeping every class node, including ids such as `cluster_Helper`. ## Java 25 analysis (JEP 238 multi-release jar) @@ -131,6 +227,11 @@ is for build failures, not for "Kotlin is absent". Generate reports directly: `mvn org.hjug.refactorfirst.plugin:refactor-first-maven-plugin:0.9.0:htmlReport` +Generate the JSON report data (writes `.refactorfirst/refactor-first.json` +at the project root; the dogfooded copy in this repo is regenerated with this +goal on the current `0.11.0-SNAPSHOT`): +`mvn org.hjug.refactorfirst.plugin:refactor-first-maven-plugin:0.11.0-SNAPSHOT:jsonReport` + Configuration options (most important): - `showDetails`: Shows God Class metrics in table (default: false) - `backEdgeAnalysisCount`: 0 = analyze all back edges (default: 50) diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/GraphDependencyCollector.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/GraphDependencyCollector.java index c312d8b5..828f0e3b 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/GraphDependencyCollector.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/GraphDependencyCollector.java @@ -132,11 +132,24 @@ public DefaultWeightedEdge addPackageDependency(String fromClassFqn, String toCl } protected String getPackageFromFqn(String fqn) { - if (!fqn.contains(".")) { + String name = fqn; + int lastIndex = name.lastIndexOf('.'); + // A trailing ""-style segment names a Kotlin anonymous class, not a package + // member: derive the package from the enclosing class so an anonymous class never + // manufactures a package named after its owner (dev.Owner. -> "dev", and + // Owner. -> "" like the bare packageless literal). This keeps the package + // graph's package names aligned with the class hierarchy's package derivation, so the + // break-up packages flagged in the Class and Package graphs match. + if (lastIndex >= 0 && name.substring(lastIndex + 1).startsWith("<")) { + name = name.substring(0, lastIndex); + if (!name.contains(".")) { + return ""; + } + lastIndex = name.lastIndexOf('.'); + } else if (lastIndex < 0) { return ""; } - int lastIndex = fqn.lastIndexOf("."); - return fqn.substring(0, lastIndex); + return name.substring(0, lastIndex); } /** diff --git a/codebase-graph-builder/src/test/java/org/hjug/graphbuilder/GraphDependencyCollectorTest.java b/codebase-graph-builder/src/test/java/org/hjug/graphbuilder/GraphDependencyCollectorTest.java index 3fe10325..86a3fc53 100644 --- a/codebase-graph-builder/src/test/java/org/hjug/graphbuilder/GraphDependencyCollectorTest.java +++ b/codebase-graph-builder/src/test/java/org/hjug/graphbuilder/GraphDependencyCollectorTest.java @@ -157,6 +157,66 @@ void addPackageDependency_kotlinAnonymousSource_doesNotPollutePackageGraph() { assertTrue(pkgGraph.edgeSet().isEmpty()); } + /** + * A prefixed Kotlin anonymous FQN (e.g. {@code dev.DeveloperWASDControl.}) must not + * manufacture a package named after its enclosing class: the package edge derives from the + * enclosing class's package, so the Class and Package graphs agree on what the packages are + * and the break-up lists rendered from them match. + */ + @DisplayName("addPackageDependency derives the enclosing class's package for a prefixed Kotlin source") + @Test + void addPackageDependency_prefixedKotlinAnonymousSource_derivesEnclosingClassPackage() { + Graph classGraph = newClassGraph(); + Graph pkgGraph = newClassGraph(); + GraphDependencyCollector collector = new GraphDependencyCollector(classGraph, pkgGraph); + + DefaultWeightedEdge edge = collector.addPackageDependency( + "dev.DeveloperWASDControl.", "com.almasb.fxgl.app.GameApplication"); + + assertNotNull(edge, "the anonymous class's dependency must create the real package edge"); + assertEquals("dev", pkgGraph.getEdgeSource(edge).getName()); + assertEquals("com.almasb.fxgl.app", pkgGraph.getEdgeTarget(edge).getName()); + Set packageNames = + pkgGraph.vertexSet().stream().map(VertexInfo::getName).collect(java.util.stream.Collectors.toSet()); + assertEquals( + Set.of("dev", "com.almasb.fxgl.app"), + packageNames, + "no pseudo-package named after the enclosing class may exist"); + } + + /** Same rule for the target side: an anonymous target derives from its enclosing class's package. */ + @DisplayName("addPackageDependency derives the enclosing class's package for a prefixed Kotlin target") + @Test + void addPackageDependency_prefixedKotlinAnonymousTarget_derivesEnclosingClassPackage() { + Graph classGraph = newClassGraph(); + Graph pkgGraph = newClassGraph(); + GraphDependencyCollector collector = new GraphDependencyCollector(classGraph, pkgGraph); + + DefaultWeightedEdge edge = collector.addPackageDependency( + "com.almasb.fxgl.app.GameApplication", "dev.DeveloperWASDControl."); + + assertNotNull(edge); + assertEquals("com.almasb.fxgl.app", pkgGraph.getEdgeSource(edge).getName()); + assertEquals("dev", pkgGraph.getEdgeTarget(edge).getName()); + assertFalse( + pkgGraph.vertexSet().stream().anyMatch(v -> v.getName().equals("dev.DeveloperWASDControl")), + "no pseudo-package named after the enclosing class may exist"); + } + + /** An anonymous class whose enclosing class has no package is a no-op, like the bare literal. */ + @DisplayName("addPackageDependency with a packageless enclosing class is a no-op") + @Test + void addPackageDependency_packagelessEnclosingAnonymous_isNoOp() { + Graph classGraph = newClassGraph(); + Graph pkgGraph = newClassGraph(); + GraphDependencyCollector collector = new GraphDependencyCollector(classGraph, pkgGraph); + + DefaultWeightedEdge edge = collector.addPackageDependency("DeveloperWASDControl.", "com.bar.Other"); + + assertNull(edge, "an anonymous class in a packageless enclosing class has no package edge"); + assertTrue(pkgGraph.vertexSet().isEmpty(), "no package vertex may be created"); + } + /** Verifies that explicit registration retains anonymous and synthetic class vertices. */ @DisplayName("registerClassVertex registers Java anonymous and Kotlin FQNs") @Test diff --git a/report/src/main/java/org/hjug/refactorfirst/report/HierarchyBuilder.java b/report/src/main/java/org/hjug/refactorfirst/report/HierarchyBuilder.java new file mode 100644 index 00000000..d6f40e5d --- /dev/null +++ b/report/src/main/java/org/hjug/refactorfirst/report/HierarchyBuilder.java @@ -0,0 +1,436 @@ +package org.hjug.refactorfirst.report; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HexFormat; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.hjug.cbc.RankedCycle; +import org.hjug.graphbuilder.CodebaseGraphDTO; +import org.hjug.graphbuilder.VertexInfo; +import org.hjug.refactorfirst.report.model.ClassNodeDTO; +import org.hjug.refactorfirst.report.model.EdgeDTO; +import org.hjug.refactorfirst.report.model.HierarchyDTO; +import org.hjug.refactorfirst.report.model.PackageNodeDTO; +import org.jgrapht.Graph; +import org.jgrapht.graph.DefaultWeightedEdge; + +/** + * Builds the nested package/class hierarchy for every generated DOT graph from the VertexInfo + * class and package graphs. + * + *

The hierarchy is the single source of truth for graph structure: packages nest as ancestor + * clusters with single-child chains collapsed into their deepest package, classes resolve to + * their owning package (including {@code $}-nested classes and Kotlin {@code } + * classes via the enclosing class's package), and packageless classes land in the synthetic + * {@link #DEFAULT_PACKAGE} bucket. The package graph additionally marks the packages that + * participate in relationships as rectangle nodes nested inside their ancestor clusters. + * + *

Node ids and labels reuse the exact rules of the previous DOT emitters — including + * source-aware ids for anonymous vertices and FQN fallback on simple-name collisions — so the + * DOT builders (Java and JavaScript) consume them verbatim. Packages flagged + * {@link PackageNodeDTO#isNeedsBreakUp()} render with a pink fill; classes and edges flagged + * {@link ClassNodeDTO#isMarkedForRemoval()} / {@link EdgeDTO#isMarkedForRemoval()} keep the red + * fill and highlighting used today. + */ +public final class HierarchyBuilder { + + /** Synthetic bucket for classes without a package. */ + public static final String DEFAULT_PACKAGE = "(default package)"; + + private HierarchyBuilder() {} + + /** + * Builds the class-map hierarchy: package clusters containing the classes that participate + * in at least one class relationship, matching the vertices the class map renders today. + * + * @param classGraph the class reference graph + * @param codebaseGraphDTO the DTO carrying the {@code vertex -> source file path} mapping + * @param classesToRemove classes selected for removal to break cycles + * @param packagesToRemove packages selected for removal to break cycles + * @param classRelationshipsToRemove class relationships selected for removal + * @return the nested package + class hierarchy with resolved ids, labels, and flags + */ + public static HierarchyDTO buildClassHierarchy( + Graph classGraph, + CodebaseGraphDTO codebaseGraphDTO, + Set classesToRemove, + Set packagesToRemove, + Set classRelationshipsToRemove) { + // the class map renders the endpoints of every class edge + Set vertexNames = new LinkedHashSet<>(); + for (DefaultWeightedEdge edge : classGraph.edgeSet()) { + vertexNames.add(classGraph.getEdgeSource(edge).getName()); + vertexNames.add(classGraph.getEdgeTarget(edge).getName()); + } + return buildClassLevelHierarchy( + classGraph, + codebaseGraphDTO, + classesToRemove, + packagesToRemove, + classRelationshipsToRemove, + vertexNames, + classGraph.edgeSet(), + true); + } + + /** + * Builds the cycle-map hierarchy restricted to the given cycle's classes and edges while + * consulting the full class graph for node id collision rules, so ids match the class map. + * + * @param cycle the ranked cycle to restrict the hierarchy to + * @return the nested package + class hierarchy for the cycle's members + */ + public static HierarchyDTO buildCycleHierarchy( + Graph classGraph, + CodebaseGraphDTO codebaseGraphDTO, + Set classesToRemove, + Set packagesToRemove, + Set classRelationshipsToRemove, + RankedCycle cycle) { + return buildClassLevelHierarchy( + classGraph, + codebaseGraphDTO, + classesToRemove, + packagesToRemove, + classRelationshipsToRemove, + new LinkedHashSet<>(cycle.getVertexSet()), + cycle.getEdgeSet(), + false); + } + + /** + * Builds the package-map hierarchy: packages participating in at least one package + * relationship join the tree (parents render once as clusters, childless packages + * once as rectangle nodes under their ancestor clusters), each carrying the + * repo-relative source directory derived from the class source mapping for the + * package graph's hyperlinks. + * + * @param packageGraph the package reference graph + * @param codebaseGraphDTO the DTO carrying the {@code vertex -> source file path} mapping + * @param packagesToRemove packages selected for removal to break cycles + * @param packageRelationshipsToRemove package relationships selected for removal + * @return the nested package hierarchy with rectangle node packages and their edges + */ + public static HierarchyDTO buildPackageHierarchy( + Graph packageGraph, + CodebaseGraphDTO codebaseGraphDTO, + Set packagesToRemove, + Set packageRelationshipsToRemove) { + // the package map renders the endpoints of every package edge + Set nodePackages = new LinkedHashSet<>(); + for (DefaultWeightedEdge edge : packageGraph.edgeSet()) { + nodePackages.add(packageGraph.getEdgeSource(edge).getName()); + nodePackages.add(packageGraph.getEdgeTarget(edge).getName()); + } + // Every break-up package must appear in the package map's flagged list, so seed the + // node set with the full removal list — belt and braces for members that take part in + // no rendered edge, keeping the Class and Package graphs' break-up lists identical. + for (VertexInfo packageToRemove : packagesToRemove) { + nodePackages.add(packageToRemove.getName()); + } + + Map packages = new HashMap<>(); + for (String name : nodePackages) { + Pkg pkg = packageNode(packages, name); + pkg.renderAsNode = true; + pkg.nodeId = HtmlReport.renderSafePackageNodeId(name); + } + // each package's hyperlink target is its source directory, taken from any mapped + // class in the package (accurate for multi-module repos) + Map packageDirs = packageSourceDirectories(codebaseGraphDTO); + for (Pkg pkg : packages.values()) { + pkg.path = packageDirs.getOrDefault(pkg.name, ""); + } + + List edges = new ArrayList<>(); + for (DefaultWeightedEdge edge : packageGraph.edgeSet()) { + String source = packageGraph.getEdgeSource(edge).getName(); + String target = packageGraph.getEdgeTarget(edge).getName(); + edges.add(EdgeDTO.builder() + .source(HtmlReport.renderSafePackageNodeId(source)) + .target(HtmlReport.renderSafePackageNodeId(target)) + .weight((int) packageGraph.getEdgeWeight(edge)) + .markedForRemoval(packageRelationshipsToRemove.contains(edge)) + .build()); + } + + HierarchyDTO hierarchy = assemble(packages, edges, packagesToRemove); + // Packages with children render as clusters — their relationships attach to an + // invisible anchor inside them via compound ltail/lhead edges — and only + // childless packages render as visible rectangle nodes, so every package name + // appears exactly once in the package graph. + markLeafPackagesAsNodes(hierarchy.getPackages()); + return hierarchy; + } + + /** + * Flips renderAsNode to leaf-ness on the assembled package tree: packages with kept + * children become cluster-only (their nodeId remains as the invisible edge anchor), + * childless packages become the visible rectangle nodes. + */ + private static void markLeafPackagesAsNodes(List packages) { + for (PackageNodeDTO pkg : packages) { + List children = pkg.getChildren() == null ? List.of() : pkg.getChildren(); + pkg.setRenderAsNode(children.isEmpty()); + markLeafPackagesAsNodes(children); + } + } + + /** + * Shared class/cycle assembly: resolves ids, labels, paths, and removal flags for the given + * vertex names, converts the given edges to id-referencing DTOs (dropping edges that touch + * suppressed sink vertices), and nests the classes into the package tree. When + * {@code includeAllBreakUpPackages} is set, every break-up package joins the tree even when + * none of its classes render, so the class map's flagged list always matches the package + * map's. + */ + private static HierarchyDTO buildClassLevelHierarchy( + Graph classGraph, + CodebaseGraphDTO codebaseGraphDTO, + Set classesToRemove, + Set packagesToRemove, + Set classRelationshipsToRemove, + Set vertexNames, + Set edges, + boolean includeAllBreakUpPackages) { + Map classesByName = new LinkedHashMap<>(); + for (String vertex : vertexNames) { + // same render-time noise filter as the class/cycle DOT emitters + if (HtmlReport.isSinkAnonymousOrSyntheticVertex(classGraph, vertex)) { + continue; + } + classesByName.put( + vertex, + ClassNodeDTO.builder() + .fqn(vertex) + .id(HtmlReport.renderSafeNodeId(vertex, classGraph, codebaseGraphDTO)) + .label( + HtmlReport.isAnonymousFqn(vertex) + ? HtmlReport.anonymousOwnerLabel(vertex, codebaseGraphDTO) + : SimpleHtmlReport.getClassName(vertex)) + .path(classSourcePath(vertex, codebaseGraphDTO)) + .markedForRemoval(classesToRemove.contains(VertexInfo.forName(vertex))) + .build()); + } + + List edgeDtos = new ArrayList<>(); + for (DefaultWeightedEdge edge : edges) { + String source = classGraph.getEdgeSource(edge).getName(); + String target = classGraph.getEdgeTarget(edge).getName(); + if (!classesByName.containsKey(source) || !classesByName.containsKey(target)) { + continue; // edge touches a suppressed sink-only anonymous/synthetic vertex + } + edgeDtos.add(EdgeDTO.builder() + .source(classesByName.get(source).getId()) + .target(classesByName.get(target).getId()) + .weight((int) classGraph.getEdgeWeight(edge)) + .markedForRemoval(classRelationshipsToRemove.contains(edge)) + .build()); + } + + Map packages = new HashMap<>(); + for (ClassNodeDTO cls : classesByName.values()) { + packageNode(packages, packageOf(cls.getFqn())).classes.add(cls); + } + if (includeAllBreakUpPackages) { + // Guarantee the class map flags the full break-up list even when a package's + // classes do not render: seed its cluster so pruning and collapse keep it. + for (VertexInfo packageToRemove : packagesToRemove) { + String name = packageToRemove.getName(); + if (!DEFAULT_PACKAGE.equals(name)) { + packageNode(packages, name); + } + } + } + + return assemble(packages, edgeDtos, packagesToRemove); + } + + /** + * Derives the owning package of a class vertex name. Nested ({@code $}) classes belong to + * the package of their name's last dot segment; Kotlin anonymous classes belong to the + * package of their enclosing class; packageless names have no package ({@code null}). + */ + static String packageOf(String fqn) { + int lastDot = fqn.lastIndexOf('.'); + String simple = lastDot >= 0 ? fqn.substring(lastDot + 1) : fqn; + if (simple.startsWith("<")) { + // Kotlin anonymous: the enclosing construct is a class, e.g. pkg.Outer + if (lastDot <= 0) { + return null; + } + String enclosing = fqn.substring(0, lastDot); + int enclosingDot = enclosing.lastIndexOf('.'); + return enclosingDot > 0 ? enclosing.substring(0, enclosingDot) : null; + } + return lastDot > 0 ? fqn.substring(0, lastDot) : null; + } + + /** Returns the source file path relative to the project root, or an empty string. */ + private static String classSourcePath(String vertex, CodebaseGraphDTO codebaseGraphDTO) { + if (codebaseGraphDTO == null || codebaseGraphDTO.getClassToSourceFilePathMapping() == null) { + return ""; + } + String path = codebaseGraphDTO.getClassToSourceFilePathMapping().get(vertex); + return path == null ? "" : path; + } + + /** + * Derives each package's repo-relative source directory (with trailing slash) from the + * mapped class source paths: {@code org.a.A -> module/src/main/java/org/a/A.java} yields + * {@code org.a -> module/src/main/java/org/a/}. The first mapped class wins. + */ + private static Map packageSourceDirectories(CodebaseGraphDTO codebaseGraphDTO) { + Map packageDirs = new HashMap<>(); + if (codebaseGraphDTO == null || codebaseGraphDTO.getClassToSourceFilePathMapping() == null) { + return packageDirs; + } + for (Map.Entry entry : + codebaseGraphDTO.getClassToSourceFilePathMapping().entrySet()) { + String packageName = packageOf(entry.getKey()); + String path = entry.getValue(); + if (packageName == null || path == null || !path.contains("/")) { + continue; + } + packageDirs.putIfAbsent(packageName, path.substring(0, path.lastIndexOf('/') + 1)); + } + return packageDirs; + } + + /** Creates (or returns) the package node for the name, creating and linking all ancestors. */ + private static Pkg packageNode(Map packages, String packageName) { + String name = packageName == null || packageName.isEmpty() ? DEFAULT_PACKAGE : packageName; + Pkg existing = packages.get(name); + if (existing != null) { + return existing; + } + Pkg pkg = new Pkg(name); + packages.put(name, pkg); + String parent = parentPackage(name); + if (parent != null) { + packageNode(packages, parent).children.add(pkg); + } + return pkg; + } + + /** Returns the parent package name, or {@code null} for top-level packages and the default bucket. */ + private static String parentPackage(String name) { + if (DEFAULT_PACKAGE.equals(name)) { + return null; + } + int dot = name.lastIndexOf('.'); + return dot > 0 ? name.substring(0, dot) : null; + } + + /** + * Flags breakup packages, prunes empty branches, collapses single-child chains, sorts every + * collection deterministically, and converts the internal tree to the DTO tree. + */ + private static HierarchyDTO assemble( + Map packages, List edges, Set packagesToRemove) { + for (Pkg pkg : packages.values()) { + if (!DEFAULT_PACKAGE.equals(pkg.name)) { + pkg.needsBreakUp = packagesToRemove.contains(VertexInfo.forName(pkg.name)); + } + } + + List roots = new ArrayList<>(); + for (Pkg pkg : packages.values()) { + if (parentPackage(pkg.name) == null) { + Pkg pruned = pruneAndCollapse(pkg); + if (pruned != null) { + roots.add(toDto(pruned)); + } + } + } + roots.sort(Comparator.comparing(PackageNodeDTO::getName)); + + edges.sort(Comparator.comparing(EdgeDTO::getSource).thenComparing(EdgeDTO::getTarget)); + return HierarchyDTO.builder().packages(roots).edges(edges).build(); + } + + /** + * Prunes branches without rendered content and collapses single-child chains: a package + * with no content of its own and exactly one kept child is replaced by that child so chains + * like {@code com -> com.foo -> com.foo.bar} render as a single cluster labelled with the + * deepest package name. + */ + private static Pkg pruneAndCollapse(Pkg pkg) { + List kept = new ArrayList<>(); + for (Pkg child : pkg.children) { + Pkg pruned = pruneAndCollapse(child); + if (pruned != null) { + kept.add(pruned); + } + } + // A flagged package is content of its own: it must never be pruned away for being + // empty, nor merged into its single child — the class map must keep listing every + // break-up package so its list matches the package map's. + boolean hasContent = pkg.renderAsNode || !pkg.classes.isEmpty() || pkg.needsBreakUp; + if (!hasContent && kept.isEmpty()) { + return null; // nothing rendered at or below this package + } + if (!hasContent && kept.size() == 1) { + return kept.get(0); // pure ancestor of a single child: merge into the child + } + pkg.children.clear(); + pkg.children.addAll(kept); + return pkg; + } + + /** Converts a pruned package subtree to the DTO tree with sorted children and classes. */ + private static PackageNodeDTO toDto(Pkg pkg) { + List children = new ArrayList<>(); + for (Pkg child : pkg.children) { + children.add(toDto(child)); + } + children.sort(Comparator.comparing(PackageNodeDTO::getName)); + + List classes = new ArrayList<>(pkg.classes); + classes.sort(Comparator.comparing(ClassNodeDTO::getFqn)); + + return PackageNodeDTO.builder() + .name(pkg.name) + .id(clusterId(pkg.name)) + .nodeId(pkg.nodeId) + .path(pkg.path) + .renderAsNode(pkg.renderAsNode) + .needsBreakUp(pkg.needsBreakUp) + .children(children) + .classes(classes) + .build(); + } + + /** Returns the deterministic DOT-safe cluster id {@code cluster_} for a package name. */ + static String clusterId(String packageName) { + try { + byte[] digest = MessageDigest.getInstance("SHA-256").digest(packageName.getBytes(StandardCharsets.UTF_8)); + return "cluster_" + HexFormat.of().formatHex(digest, 0, 12); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException("SHA-256 is required by the Java runtime", e); + } + } + + /** Mutable internal package tree node used while assembling the hierarchy. */ + private static final class Pkg { + final String name; + final List children = new ArrayList<>(); + final List classes = new ArrayList<>(); + String nodeId; + String path = ""; + boolean renderAsNode; + boolean needsBreakUp; + + Pkg(String name) { + this.name = name; + } + } +} diff --git a/report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java b/report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java index 6f6c3b34..6cac5306 100644 --- a/report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java +++ b/report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java @@ -10,6 +10,7 @@ import org.hjug.gdg.GraphDataGenerator; import org.hjug.graphbuilder.CodebaseGraphDTO; import org.hjug.graphbuilder.VertexInfo; +import org.hjug.refactorfirst.report.model.HierarchyDTO; import org.jgrapht.Graph; import org.jgrapht.graph.DefaultWeightedEdge; @@ -102,7 +103,21 @@ function renderGraph(dot) { // Convert graphlib graph to graphology graph const graphologyGraph = new graphology.Graph(); + // graphlib-dot creates a node for every named subgraph and + // parents the nodes it contains to it (empty subgraphs are + // removed): in the class map that is one cluster node per + // package, labelled with the package name. Packages are noise + // in the popups, so drop the subgraph nodes — identified by + // their children, never by the cluster_ id prefix, which real + // class ids like cluster_Helper can share — while keeping + // every node the clusters contained and the edges between + // them. + const droppedClusters = new Set(); graphlibGraph.nodes().forEach(node => { + if (graphlibGraph.children(node).length > 0) { + droppedClusters.add(node); + return; + } const attrs = graphlibGraph.node(node); graphologyGraph.addNode(node, { label: attrs.label || node, @@ -112,6 +127,7 @@ function renderGraph(dot) { }); graphlibGraph.edges().forEach(edge => { + if (droppedClusters.has(edge.v) || droppedClusters.has(edge.w)) return; const attrs = graphlibGraph.edge(edge); graphologyGraph.addEdge(edge.v, edge.w, { color: attrs.color, @@ -151,7 +167,18 @@ function createForceGraph(popupId, containerName, dot) { var nodes = []; var links = []; + // Packages are noise in the popups: drop the subgraph + // nodes graphlib-dot creates per named subgraph — + // identified by their children, never by the cluster_ + // id prefix, which real class ids like cluster_Helper + // can share — keeping every node they contained and + // the edges between the kept nodes. + var droppedClusters = new Set(); graphlibGraph.nodes().forEach(function (node) { + if (graphlibGraph.children(node).length > 0) { + droppedClusters.add(node); + return; + } var nodeData = graphlibGraph.node(node); nodes.push({ id: node, @@ -161,6 +188,7 @@ function createForceGraph(popupId, containerName, dot) { }); graphlibGraph.edges().forEach(function (edge) { + if (droppedClusters.has(edge.v) || droppedClusters.has(edge.w)) return; links.push({ source: edge.v, target: edge.w, @@ -550,6 +578,9 @@ private static String generateDotImage(String graphName) { + graphName + "_dot);\n" + " const directedGraph = dotGraph.to_directed();\n" + " const positioned = directedGraph.layout();\n" + " let svg = positioned.to_svg().to_string();\n" + + " // vizdom drops the target attribute on hyperlinked nodes; restore new-tab\n" + + " // behavior on every anchor (a graph hyperlinks many nodes)\n" + + " svg = svg.replace(/\n"; } - /** Builds raw DOT source for the complete class relationship graph. */ + /** + * Builds raw DOT source for the complete class relationship graph as nested package + * clusters containing the classes that participate in at least one relationship. + */ String buildRawClassGraphDot( Graph classGraph, String repoUrl, CodebaseGraphDTO codebaseGraphDTO) { - StringBuilder dot = new StringBuilder(); - dot.append("strict digraph G {\n"); - - for (DefaultWeightedEdge edge : classGraph.edgeSet()) { - renderClassGraphEdge(classGraph, edge, codebaseGraphDTO, dot); - } - - // capture only classes that have a relationship with one or more other classes - Set vertexesToRender = new HashSet<>(); - for (DefaultWeightedEdge edge : classGraph.edgeSet()) { - String[] vertexes = extractVertexes(edge); - String originVertex = vertexes[0].trim(); - vertexesToRender.add(originVertex); - vertexesToRender.add(vertexes[1].trim()); - } - - // render vertices - renderClassVertices(classGraph, repoUrl, codebaseGraphDTO, vertexesToRender, dot); - - dot.append("}"); - return dot.toString(); + HierarchyDTO hierarchy = HierarchyBuilder.buildClassHierarchy( + classGraph, codebaseGraphDTO, classesToRemove, packagesToRemove, classRelationshipsToRemove); + return NestedDotBuilder.buildNestedDot(hierarchy, repoUrl, true); } /** Builds escaped class-graph DOT suitable for a JavaScript template literal. */ @@ -596,184 +612,40 @@ String buildClassGraphDot( } /** - * Appends class DOT nodes, omitting sink-only anonymous or synthetic vertices and labels that - * match their node IDs. Includes source-link attributes supplied by the report and highlights - * classes selected for removal. + * Encodes a full class name as an injective ASCII DOT identifier. ASCII letters and digits + * pass through; every other UTF-16 code unit (including underscores) becomes an underscore + * followed by four hex digits. Escaping the escape marker makes the encoding reversible, + * including for supplementary characters. The class_ prefix avoids DOT keywords, leading + * digits, and the package_/cluster_ namespaces. Human-readable names remain in DTO labels. */ - private void renderClassVertices( - Graph classGraph, - String repoUrl, - CodebaseGraphDTO codebaseGraphDTO, - Set vertexesToRender, - StringBuilder dot) { - for (String vertex : vertexesToRender) { - String className = getClassName(vertex); - - // Suppress sink-only anonymous/synthetic vertices (no outgoing edges) so the DOT graph - // stays readable; active anonymous/synthetic classes still render. - if (isSinkAnonymousOrSyntheticVertex(classGraph, vertex)) { - continue; - } - - String safeNodeId = renderSafeNodeId(vertex, classGraph, codebaseGraphDTO); - dot.append(safeNodeId); - - dot.append(" ["); - dot.append(hyperlinkClassForDot(vertex, repoUrl, codebaseGraphDTO)); - - String label; - if (isAnonymousFqn(vertex)) { - // Kotlin "" renders under the enclosing source file's base name as the - // owner with $ as the enclosing-class separator (escaped for DOT). - label = escapeDotQuoted(anonymousOwnerLabel(vertex, codebaseGraphDTO)); + static String renderSafeNodeId(String vertex) { + StringBuilder id = new StringBuilder("class_"); + for (int i = 0; i < vertex.length(); i++) { + char c = vertex.charAt(i); + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) { + id.append(c); } else { - label = escapeDotQuoted(className); - } - - if (!label.equals(safeNodeId)) { - dot.append(" label=\"").append(label).append("\""); + String hex = Integer.toHexString(c); + id.append('_').append("0".repeat(4 - hex.length())).append(hex); } - - if (classesToRemove.contains(VertexInfo.forName(vertex))) { - dot.append(" color=red style=filled"); - } - - dot.append("];\n"); - } - } - - String hyperlinkClassForDot(String fqClassName, String repoUrl, CodebaseGraphDTO codebaseGraphDTO) { - if (codebaseGraphDTO == null || codebaseGraphDTO.getClassToSourceFilePathMapping() == null) { - return ""; - } - String path = codebaseGraphDTO.getClassToSourceFilePathMapping().get(fqClassName); - if (path == null || path.isBlank()) { - return ""; } - return "URL=\"" + escapeDotQuoted(repoUrl + path) + "\" target=\"_blank\""; - } - - /** - * Returns the DOT-safe node id for a class vertex. This is the fully qualified class name - * with {@code .} replaced by {@code _} and {@code $} replaced by {@code _} (for inner classes), - * extended to also handle the Kotlin literal {@code ""} FQN, - * whose {@code <}/{@code >} characters are illegal in Graphviz node ids. - * When the source-file mapping is unavailable ({@code codebaseGraphDTO == null} or no path - * is mapped for the vertex), {@code <}/{@code >} are reversibly encoded as {@code lt_}/{@code _gt}. - * Prefer the {@link #renderSafeNodeId(String, CodebaseGraphDTO)} overload, which is source-aware - * for anonymous vertices. - * - * @param vertex the fully qualified (or literal) class vertex name - * @return a deterministic DOT-legal node id derived from the fully qualified class name - */ - String renderSafeNodeId(String vertex) { - // Full FQN with dots→underscores for uniqueness across packages (Option A) - // $ -> _ (Java inner/anonymous convention) - // < -> lt_ and > -> _gt (Kotlin literal) - return vertex.replace(".", "_").replace("$", "_").replace("<", "lt_").replace(">", "_gt"); + return id.toString(); } - /** - * Source-aware DOT node id. For an anonymous Kotlin vertex (literal {@code ""} or - * any {@code <...>} FQN) the enclosing owner is recovered from the source-file path mapped in - * {@code codebaseGraphDTO.classToSourceFilePathMapping}: the source file's base name without - * extension (e.g. {@code DeveloperWASDControl.kt} -> {@code DeveloperWASDControl}). The - * resulting DOT id is {@code _anonymous}, which is {@code <}/{@code >}-free and human - * recognizable. When no source path is mapped (or {@code codebaseGraphDTO == null}) this - * degrades to {@link #renderSafeNodeId(String)} (the {@code lt_anonymous_gt} encoding). - * - *

For non-anonymous vertices this is identical to {@link #renderSafeNodeId(String)}. - * - * @param vertex the fully qualified (or literal) class vertex name - * @param codebaseGraphDTO the DTO carrying the {@code vertex -> source file path} mapping - * @return a deterministic DOT-legal node id for the vertex - */ + /** Source mappings affect labels only; class identity always comes from the full name. */ String renderSafeNodeId(String vertex, CodebaseGraphDTO codebaseGraphDTO) { - if (isAnonymousFqn(vertex)) { - String owner = enclosingSourceFileBaseName(vertex, codebaseGraphDTO); - if (owner != null) { - // Append hash of FQN to prevent collisions between anonymous classes - // from same-named files in different packages - String discriminator = String.valueOf(Math.abs(vertex.hashCode())); - return owner.replace("$", "_") + "_anonymous_" + discriminator; - } - } return renderSafeNodeId(vertex); } - /** - * Graph-aware DOT node id. Uses simple class name when unique across the graph, - * falls back to full FQN with dots→underscores when collision exists. - * Special handling for anonymous/synthetic vertices (uses lt_anonymous_gt encoding), - * inner classes (always uses FQN), and anonymous with enclosing prefix. - * - * @param vertex the fully qualified (or literal) class vertex name - * @param classGraph the class graph for collision detection - * @return a deterministic DOT-legal node id for the vertex - */ + /** Class ids remain stable across full-graph and cycle views. */ String renderSafeNodeId(String vertex, Graph classGraph) { - return renderSafeNodeId(vertex, classGraph, null); + return renderSafeNodeId(vertex); } - /** - * Graph-aware DOT node id with DTO support. Uses simple class name when unique across the graph, - * falls back to full FQN with dots→underscores when collision exists. - * Special handling for anonymous/synthetic vertices (uses lt_anonymous_gt encoding or - * source-aware ID from DTO), inner classes (always uses FQN), and anonymous with enclosing prefix. - * - * @param vertex the fully qualified (or literal) class vertex name - * @param classGraph the class graph for collision detection - * @param codebaseGraphDTO optional DTO for source-aware anonymous vertex IDs - * @return a deterministic DOT-legal node id for the vertex - */ - String renderSafeNodeId( + /** Resolves the same class id regardless of graph membership or source-file mappings. */ + static String renderSafeNodeId( String vertex, Graph classGraph, CodebaseGraphDTO codebaseGraphDTO) { - // Special handling for anonymous/synthetic vertices - if (isAnonymousFqn(vertex)) { - // If DTO provided, try to get source-aware ID - if (codebaseGraphDTO != null) { - String owner = enclosingSourceFileBaseName(vertex, codebaseGraphDTO); - if (owner != null) { - return owner.replace("$", "_") + "_anonymous"; - } - } - // No DTO or no source mapping: use lt_anonymous_gt encoding - return vertex.replace(".", "_") - .replace("$", "_") - .replace("<", "lt_") - .replace(">", "_gt"); - } - - // Check if this is an anonymous class with enclosing class prefix (e.g., dev.Class.) - if (vertex.contains(".")) { - return vertex.replace(".", "_") - .replace("$", "_") - .replace("<", "lt_") - .replace(">", "_gt"); - } - - // Check if this is an inner class (contains $) - if (vertex.contains("$")) { - // Inner classes always use FQN-based ID - return vertex.replace(".", "_").replace("$", "_"); - } - - // For regular classes, check if simple name is unique in the graph - String simpleName = getClassName(vertex); - - // Count occurrences of this simple name in the graph - long count = classGraph.vertexSet().stream() - .map(graphVertex -> getClassName(graphVertex.getName())) - .filter(simpleName::equals) - .count(); - - if (count == 1) { - // Unique simple name - use it (with $/< > escaping for safety) - return simpleName.replace("$", "_").replace("<", "lt_").replace(">", "_gt"); - } else { - // Collision - use full FQN with dots→underscores - return vertex.replace(".", "_").replace("$", "_"); - } + return renderSafeNodeId(vertex); } /** @@ -782,7 +654,7 @@ String renderSafeNodeId( * {@code DeveloperWASDControl}. Returns {@code null} when the vertex has no mapped source * path or {@code codebaseGraphDTO == null}. */ - private String enclosingSourceFileBaseName(String vertex, CodebaseGraphDTO codebaseGraphDTO) { + private static String enclosingSourceFileBaseName(String vertex, CodebaseGraphDTO codebaseGraphDTO) { if (codebaseGraphDTO == null) { return null; } @@ -813,7 +685,7 @@ private String enclosingSourceFileBaseName(String vertex, CodebaseGraphDTO codeb * e.g. {@code DeveloperWASDControl$anonymous} -> {@code DeveloperWASDControl\$anonymous}. * Falls back to the raw class name (e.g. {@code }) when no owner is recoverable. */ - private String anonymousOwnerLabel(String vertex, CodebaseGraphDTO codebaseGraphDTO) { + static String anonymousOwnerLabel(String vertex, CodebaseGraphDTO codebaseGraphDTO) { String owner = enclosingSourceFileBaseName(vertex, codebaseGraphDTO); String simple = getClassName(vertex); if (owner != null) { @@ -828,7 +700,7 @@ private String anonymousOwnerLabel(String vertex, CodebaseGraphDTO codebaseGraph * trailing simple-name segment, either standalone ({@code ""}) or prefixed by the * enclosing class/package (e.g. {@code "dev.DeveloperWASDControl."}). Such a * vertex cannot appear verbatim in a DOT node id (the {@code <}/{@code >} are illegal), so - * this predicate decides when the source-aware id/label derivation must kick in. + * this predicate decides when the source-aware label derivation must kick in. */ static boolean isAnonymousFqn(String vertex) { if (vertex == null) { @@ -892,50 +764,6 @@ private static String simpleNameAfterLastDollar(String vertex) { return dollar >= 0 ? afterDot.substring(dollar + 1) : afterDot; } - /** Appends a weighted class edge to DOT, highlighting removals and suppressing edges to hidden sink vertices. */ - private void renderClassGraphEdge( - Graph classGraph, - DefaultWeightedEdge edge, - CodebaseGraphDTO codebaseGraphDTO, - StringBuilder dot) { - // render edge - String[] vertexes = extractVertexes(edge); - - String startVertex = vertexes[0].trim(); - String start = renderSafeNodeId(startVertex, classGraph, codebaseGraphDTO); - String endVertex = vertexes[1].trim(); - String end = renderSafeNodeId(endVertex, classGraph, codebaseGraphDTO); - - // Suppress edges that touch a sink-only anonymous/synthetic vertex; the vertex itself is - // skipped in renderClassVertices, so an edge pointing at (or from) it would dangle. - if (isSinkAnonymousOrSyntheticVertex(classGraph, startVertex) - || isSinkAnonymousOrSyntheticVertex(classGraph, endVertex)) { - log.debug("Skipping edge touching a sink anonymous/synthetic vertex: {} -> {}", startVertex, endVertex); - return; - } - - log.debug("Rendering edge: {} -> {}", startVertex, endVertex); - dot.append(start); - dot.append(" -> "); - dot.append(end); - - // render edge attributes - int edgeWeight = (int) classGraph.getEdgeWeight(edge); - dot.append(" [ "); - dot.append("label = \""); - dot.append(edgeWeight); - dot.append("\" "); - dot.append("weight = \""); - dot.append(edgeWeight); - dot.append("\""); - - if (classRelationshipsToRemove.contains(edge)) { - dot.append(" color = \"red\""); - } - - dot.append(" ];\n"); - } - @Override public String renderClassCycleVisuals(RankedCycle cycle, String repoUrl, CodebaseGraphDTO codebaseGraphDTO) { String dot = buildClassCycleDot(classGraph, cycle, repoUrl, codebaseGraphDTO); @@ -963,25 +791,18 @@ public String renderClassCycleVisuals(RankedCycle cycle, String repoUrl, Codebas return stringBuilder.toString(); } - /** Builds raw DOT source for a ranked class cycle. */ + /** + * Builds raw DOT source for a ranked class cycle as nested package clusters, consulting the + * full class graph for the cycle members' node ids. + */ String buildRawClassCycleDot( Graph classGraph, RankedCycle cycle, String repoUrl, CodebaseGraphDTO codebaseGraphDTO) { - StringBuilder dot = new StringBuilder(); - dot.append("strict digraph G {\n"); - - for (DefaultWeightedEdge edge : cycle.getEdgeSet()) { - renderClassGraphEdge(classGraph, edge, codebaseGraphDTO, dot); - } - - // render vertices - Set vertexSet = cycle.getVertexSet(); - renderClassVertices(classGraph, repoUrl, codebaseGraphDTO, vertexSet, dot); - - dot.append("}"); - return dot.toString(); + HierarchyDTO hierarchy = HierarchyBuilder.buildCycleHierarchy( + classGraph, codebaseGraphDTO, classesToRemove, packagesToRemove, classRelationshipsToRemove, cycle); + return NestedDotBuilder.buildNestedDot(hierarchy, repoUrl, true); } /** Builds escaped class-cycle DOT suitable for a JavaScript template literal. */ @@ -1027,29 +848,18 @@ public String renderPackageGraphVisuals(String repoUrl, CodebaseGraphDTO codebas return stringBuilder.toString(); } - /** Builds raw DOT source for the package relationship graph. */ + /** + * Builds raw DOT source for the package relationship graph: one ellipse node per + * participating package and the relationship edges between them — the main-branch + * package map, rendered by vizdom like the class and cycle graphs. The + * {@code repoUrl} and {@code codebaseGraphDTO} parameters are retained for + * signature compatibility; the full hierarchy stays in refactor-first.json. + */ String buildRawPackageGraphDot( Graph packageGraph, String repoUrl, CodebaseGraphDTO codebaseGraphDTO) { - StringBuilder dot = new StringBuilder(); - dot.append("strict digraph G {\n"); - - for (DefaultWeightedEdge edge : packageGraph.edgeSet()) { - renderPackageGraphEdge(packageGraph, edge, dot); - } - - // capture only classes that have a relationship with one or more other classes - Set vertexesToRender = new HashSet<>(); - for (DefaultWeightedEdge edge : packageGraph.edgeSet()) { - String[] vertexes = extractVertexes(edge); - vertexesToRender.add(vertexes[0].trim()); - vertexesToRender.add(vertexes[1].trim()); - } - - // render vertices - renderPackageVertices(packageGraph, repoUrl, codebaseGraphDTO, vertexesToRender, dot); - - dot.append("}"); - return dot.toString(); + HierarchyDTO hierarchy = HierarchyBuilder.buildPackageHierarchy( + packageGraph, codebaseGraphDTO, packagesToRemove, packageRelationshipsToRemove); + return NestedDotBuilder.buildPackageDot(hierarchy, repoUrl); } /** Builds escaped package-graph DOT suitable for a JavaScript template literal. */ @@ -1058,59 +868,6 @@ String buildPackageGraphDot( return toJavaScriptTemplateLiteral(buildRawPackageGraphDot(packageGraph, repoUrl, codebaseGraphDTO)); } - /** Appends a weighted package edge to DOT, using safe node IDs and highlighting selected removals. */ - private void renderPackageGraphEdge( - Graph packageGraph, DefaultWeightedEdge edge, StringBuilder dot) { - // render edge - String[] vertexes = extractVertexes(edge); - - String start = renderSafePackageNodeId(vertexes[0].trim()); - String end = renderSafePackageNodeId(vertexes[1].trim()); - - log.debug("Rendering edge: {} -> {}", start, end); - dot.append(start); - dot.append(" -> "); - dot.append(end); - - // render edge attributes - int edgeWeight = (int) packageGraph.getEdgeWeight(edge); - dot.append(" [ "); - dot.append("label = \""); - dot.append(edgeWeight); - dot.append("\" "); - dot.append("weight = \""); - dot.append(edgeWeight); - dot.append("\""); - - if (packageRelationshipsToRemove.contains(edge)) { - dot.append(" color = \"red\""); - } - - dot.append(" ];\n"); - } - - /** Appends escaped package nodes to DOT and highlights packages selected for removal. */ - private void renderPackageVertices( - Graph classGraph, - String repoUrl, - CodebaseGraphDTO codebaseGraphDTO, - Set vertexesToRender, - StringBuilder dot) { - for (String packageName : vertexesToRender) { - dot.append(renderSafePackageNodeId(packageName)); - - dot.append(" [label=\""); - dot.append(escapeDotQuoted(packageName)); - dot.append("\""); - - if (packagesToRemove.contains(VertexInfo.forName(packageName))) { - dot.append(" color=red style=filled"); - } - - dot.append("];\n"); - } - } - static String renderSafePackageNodeId(String packageName) { try { byte[] digest = MessageDigest.getInstance("SHA-256").digest(packageName.getBytes(StandardCharsets.UTF_8)); diff --git a/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java b/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java index 4fc81f7f..689ef245 100644 --- a/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java +++ b/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java @@ -82,17 +82,6 @@ public void execute( // copyViewerResources(dotRefactorFirstDir); } - /** - * Intentionally excluding hyperlinks in DOT to reduce JSON file size - * - * @param fqClassName The fully qualified class name - * @param repoUrl The repo URL - * @param codebaseGraphDTO The DTO containing the codebase graph - */ - String hyperlinkClassForDot(String fqClassName, String repoUrl, CodebaseGraphDTO codebaseGraphDTO) { - return ""; - } - /** Copies the Mustache template and browser viewer into the report directory. */ private void copyViewerResources(Path targetDir) { try { @@ -250,14 +239,15 @@ public RefactorFirstReportDTO generateReportData( // 1. Class Map int classCount = classGraph.vertexSet().size(); int classRelationshipCount = classGraph.edgeSet().size(); - String classGraphDot = buildRawClassGraphDot(classGraph, repoUrl, codebaseGraphDTO); + HierarchyDTO classGraphHierarchy = HierarchyBuilder.buildClassHierarchy( + classGraph, codebaseGraphDTO, classesToRemove, packagesToRemove, classRelationshipsToRemove); GraphVisualDTO classMapDTO = GraphVisualDTO.builder() .graphId("classGraph") .classCount(classCount) .relationshipCount(classRelationshipCount) .dotThreshold(dotGraphThreshold) .dotThresholdExceeded(classCount + classRelationshipCount >= dotGraphThreshold) - .dot(classGraphDot) + .hierarchy(classGraphHierarchy) .build(); // 2. Class Relationships To Remove @@ -296,8 +286,8 @@ public RefactorFirstReportDTO generateReportData( int packageCount = packageGraph.vertexSet().size(); int packageRelationshipCount = packageGraph.edgeSet().size(); boolean hasPackageEdges = !packageGraph.edgeSet().isEmpty(); - String packageGraphDot = - hasPackageEdges ? buildRawPackageGraphDot(packageGraph, repoUrl, codebaseGraphDTO) : ""; + HierarchyDTO packageGraphHierarchy = HierarchyBuilder.buildPackageHierarchy( + packageGraph, codebaseGraphDTO, packagesToRemove, packageRelationshipsToRemove); GraphVisualDTO packageMapDTO = GraphVisualDTO.builder() .hasEdges(hasPackageEdges) .graphId("packageGraph") @@ -305,7 +295,7 @@ public RefactorFirstReportDTO generateReportData( .relationshipCount(packageRelationshipCount) .dotThreshold(dotGraphThreshold) .dotThresholdExceeded(packageCount + packageRelationshipCount >= dotGraphThreshold) - .dot(packageGraphDot) + .hierarchy(packageGraphHierarchy) .build(); // 4. Package Relationships To Remove @@ -429,7 +419,13 @@ public RefactorFirstReportDTO generateReportData( String cycleIdentifier = graphIdentifier(cycleName); int cCount = largestCycle.getCycleNodes().size(); int rCount = largestCycle.getEdgeSet().size(); - String cycleDot = buildRawClassCycleDot(classGraph, largestCycle, repoUrl, codebaseGraphDTO); + HierarchyDTO cycleHierarchy = HierarchyBuilder.buildCycleHierarchy( + classGraph, + codebaseGraphDTO, + classesToRemove, + packagesToRemove, + classRelationshipsToRemove, + largestCycle); List breakdown = new ArrayList<>(); for (String vertex : largestCycle.getVertexSet()) { @@ -466,7 +462,7 @@ public RefactorFirstReportDTO generateReportData( .classCount(cCount) .relationshipCount(rCount) .dotThresholdExceeded(cCount + rCount >= dotGraphThreshold) - .dot(cycleDot) + .hierarchy(cycleHierarchy) .breakdown(breakdown) .build(); } @@ -751,14 +747,19 @@ private static String graphIdentifier(String value) { return "graph_" + sanitized + "_" + Integer.toUnsignedString(original.hashCode(), 36); } - /** Checks if a class belongs to a given package by checking the fully qualified class name. */ - private boolean isClassInPackage(String className, String packageName, CodebaseGraphDTO codebaseGraphDTO) { + /** + * Checks if a class belongs to a given package, deriving the class's package with the same + * rule the graphs use ({@link HierarchyBuilder#packageOf}, mirroring + * {@code GraphDependencyCollector.getPackageFromFqn}): a Kotlin anonymous class belongs to + * its enclosing class's package ({@code dev.Owner. -> dev}), and packageless + * classes match no package. + */ + boolean isClassInPackage(String className, String packageName, CodebaseGraphDTO codebaseGraphDTO) { if (className == null || packageName == null) { return false; } - // Check if the class name starts with the package name followed by a dot - int lastDot = className.lastIndexOf('.'); - return lastDot > 0 && className.substring(0, lastDot).equals(packageName); + String classPackage = HierarchyBuilder.packageOf(className); + return classPackage != null && classPackage.equals(packageName); } /** diff --git a/report/src/main/java/org/hjug/refactorfirst/report/NestedDotBuilder.java b/report/src/main/java/org/hjug/refactorfirst/report/NestedDotBuilder.java new file mode 100644 index 00000000..6dddffcf --- /dev/null +++ b/report/src/main/java/org/hjug/refactorfirst/report/NestedDotBuilder.java @@ -0,0 +1,206 @@ +package org.hjug.refactorfirst.report; + +import java.util.List; +import org.hjug.refactorfirst.report.model.ClassNodeDTO; +import org.hjug.refactorfirst.report.model.EdgeDTO; +import org.hjug.refactorfirst.report.model.HierarchyDTO; +import org.hjug.refactorfirst.report.model.PackageNodeDTO; + +/** + * Renders a {@link HierarchyDTO} in two modes: the class/cycle maps as nested DOT (packages + * become labelled clusters, classes become ellipse nodes inside their owning package cluster), + * and the package map as the flat relationship graph — one ellipse per participating package + * with only the relationship edges, matching the main-branch package map. + * + *

Visual contract: classes marked for removal keep the {@code color=red style=filled} fill + * in the class/cycle maps; packages flagged for breakup fill red in the flat package map, + * and relationships flagged for removal render red everywhere. + * + *

Clusters are emitted before the edges so every node keeps its cluster scope: in DOT a node + * belongs to the cluster where it is first defined, and edges declared afterwards may freely + * connect nodes across clusters. Edges keep the exact attribute format of the previous emitters + * and reference the ids pre-resolved in the hierarchy. + */ +public final class NestedDotBuilder { + + private NestedDotBuilder() {} + + /** + * Renders the hierarchy as nested DOT. + * + * @param hierarchy the nested package/class hierarchy + * @param repoUrl repository URL prefix for class hyperlinks + * @param includeHyperlinks whether class nodes carry {@code URL} attributes + * @return DOT source for a strict digraph whose packages nest as clusters + */ + public static String buildNestedDot(HierarchyDTO hierarchy, String repoUrl, boolean includeHyperlinks) { + StringBuilder dot = new StringBuilder(); + dot.append("strict digraph G {\n"); + if (hierarchy != null) { + if (hierarchy.getPackages() != null) { + for (PackageNodeDTO pkg : hierarchy.getPackages()) { + renderPackage(pkg, repoUrl, includeHyperlinks, dot); + } + } + if (hierarchy.getEdges() != null) { + for (EdgeDTO edge : hierarchy.getEdges()) { + renderEdge(edge, dot); + } + } + } + dot.append("}"); + return dot.toString(); + } + + /** Appends one package cluster: label, explicit fill, its node, its classes, and children. */ + private static void renderPackage( + PackageNodeDTO pkg, String repoUrl, boolean includeHyperlinks, StringBuilder dot) { + dot.append("subgraph ").append(pkg.getId()).append(" {\n"); + dot.append("label=\"").append(HtmlReport.escapeDotQuoted(pkg.getName())).append("\";\n"); + // Every cluster declares an explicit fill: vizdom propagates a styled cluster's fill + // to its nested cluster rects, so an unflagged child of a pink break-up cluster must + // say white explicitly or it would inherit the pink. White is vizdom's default + // cluster fill, so unflagged clusters look unchanged. + if (pkg.isNeedsBreakUp() && !pkg.isRenderAsNode()) { + dot.append("style=filled fillcolor=pink;\n"); + } else { + dot.append("style=filled fillcolor=white;\n"); + } + if (pkg.isRenderAsNode()) { + dot.append(pkg.getNodeId()) + .append(" [label=\"") + .append(HtmlReport.escapeDotQuoted(pkg.getName())) + .append("\" shape=rectangle"); + if (pkg.isNeedsBreakUp()) { + dot.append(" color=pink style=filled"); + } + dot.append("];\n"); + } + List classes = pkg.getClasses() == null ? List.of() : pkg.getClasses(); + for (ClassNodeDTO cls : classes) { + renderClassNode(cls, repoUrl, includeHyperlinks, dot); + } + List children = pkg.getChildren() == null ? List.of() : pkg.getChildren(); + for (PackageNodeDTO child : children) { + renderPackage(child, repoUrl, includeHyperlinks, dot); + } + dot.append("}\n"); + } + + /** + * Appends one class node: label, ellipse shape, the red removal fill, then the hyperlink. + * The {@code URL}/{@code target} attributes come last — mirroring the package nodes — and + * are emitted only when the constructed URL passes the http(s) validation the package + * hyperlinks apply. + */ + private static void renderClassNode( + ClassNodeDTO cls, String repoUrl, boolean includeHyperlinks, StringBuilder dot) { + dot.append(cls.getId()).append(" ["); + if (!cls.getLabel().equals(cls.getId())) { + dot.append(" label=\"") + .append(HtmlReport.escapeDotQuoted(cls.getLabel())) + .append("\""); + } + dot.append(" shape=ellipse"); + if (cls.isMarkedForRemoval()) { + dot.append(" color=red style=filled"); + } + if (includeHyperlinks && cls.getPath() != null && !cls.getPath().isBlank()) { + String url = (repoUrl == null ? "" : repoUrl) + cls.getPath(); + if (isHttpUrl(url)) { + dot.append(" URL=\"").append(HtmlReport.escapeDotQuoted(url)).append("\" target=\"_blank\""); + } + } + dot.append("];\n"); + } + + /** + * Renders the package-map hierarchy as the flat relationship graph: every + * package that participates in at least one relationship (or was selected for + * removal to break cycles) renders once as an ellipse node carrying its name, + * and the edges carry only the relationship weights — matching the + * main-branch package map, rendered by vizdom like the class and cycle maps. + * Packages flagged {@code needsBreakUp} fill red; relationships flagged for + * removal render red. Packages with a source path also carry a hyperlink — + * {@code URL} + {@code target="_blank"} — built from the repository URL + * prefix; only http(s) URLs are ever emitted. The full hierarchy stays in + * refactor-first.json for LLM consumption; only the relationship information + * renders. + * + * @param hierarchy the package-map hierarchy + * @param repoUrl repository URL prefix for package hyperlinks + * @return DOT source for a strict digraph of ellipse package nodes and edges + */ + public static String buildPackageDot(HierarchyDTO hierarchy, String repoUrl) { + StringBuilder dot = new StringBuilder(); + dot.append("strict digraph G {\n"); + if (hierarchy != null) { + List packages = hierarchy.getPackages() == null ? List.of() : hierarchy.getPackages(); + renderFlatPackageNodes(packages, repoUrl, dot); + List edges = hierarchy.getEdges() == null ? List.of() : hierarchy.getEdges(); + for (EdgeDTO edge : edges) { + renderEdge(edge, dot); + } + } + dot.append("}"); + return dot.toString(); + } + + /** Appends one ellipse node for every package in the tree that carries a node id. */ + private static void renderFlatPackageNodes(List packages, String repoUrl, StringBuilder dot) { + for (PackageNodeDTO pkg : packages) { + if (pkg.getNodeId() != null) { + dot.append(pkg.getNodeId()) + .append(" [label=\"") + .append(HtmlReport.escapeDotQuoted(pkg.getName())) + .append("\" shape=ellipse"); + if (pkg.isNeedsBreakUp()) { + dot.append(" color=red style=filled"); + } + String url = packageHyperlinkUrl(pkg, repoUrl); + if (url != null) { + dot.append(" URL=\"") + .append(HtmlReport.escapeDotQuoted(url)) + .append("\" target=\"_blank\""); + } + dot.append("];\n"); + } + renderFlatPackageNodes(pkg.getChildren() == null ? List.of() : pkg.getChildren(), repoUrl, dot); + } + } + + /** + * Returns the package node's hyperlink target when the repository URL and the + * package's source directory resolve to an http(s) URL; {@code null} otherwise. + */ + private static String packageHyperlinkUrl(PackageNodeDTO pkg, String repoUrl) { + if (pkg.getPath() == null || pkg.getPath().isEmpty()) { + return null; + } + String url = (repoUrl == null ? "" : repoUrl) + pkg.getPath(); + return isHttpUrl(url) ? url : null; + } + + /** Only http(s) URLs may become links. */ + private static boolean isHttpUrl(String url) { + try { + java.net.URI parsed = java.net.URI.create(url.replace(" ", "%20")); + String scheme = parsed.getScheme(); + return parsed.getHost() != null && ("http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme)); + } catch (IllegalArgumentException e) { + return false; + } + } + + /** Appends one weighted edge, red when the relationship is marked for removal. */ + private static void renderEdge(EdgeDTO edge, StringBuilder dot) { + dot.append(edge.getSource()).append(" -> ").append(edge.getTarget()); + dot.append(" [ "); + dot.append("label = \"").append(edge.getWeight()).append("\" "); + dot.append("weight = \"").append(edge.getWeight()).append("\""); + if (edge.isMarkedForRemoval()) { + dot.append(" color = \"red\""); + } + dot.append(" ];\n"); + } +} diff --git a/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java b/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java index 603c5fee..0688d1fc 100644 --- a/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java +++ b/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java @@ -1234,7 +1234,7 @@ String renderDisharmonyChart(String anchorId, String title, ListCarries the pre-resolved DOT node id and display label so renderers reuse the exact id + * logic of the previous DOT emitters, including source-aware ids for Kotlin anonymous classes. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ClassNodeDTO { + + /** Fully qualified class name (or literal anonymous vertex name). */ + private String fqn; + + /** Pre-resolved DOT-safe node id from the existing safe-id rules. */ + private String id; + + /** Display label: the simple class name, or the anonymous owner label. */ + private String label; + + /** Source file path relative to the project root, or an empty string when unknown. */ + private String path; + + /** Whether the class was selected for removal to break cycles (red fill). */ + private boolean markedForRemoval; +} diff --git a/report/src/main/java/org/hjug/refactorfirst/report/model/EdgeDTO.java b/report/src/main/java/org/hjug/refactorfirst/report/model/EdgeDTO.java new file mode 100644 index 00000000..23a426ee --- /dev/null +++ b/report/src/main/java/org/hjug/refactorfirst/report/model/EdgeDTO.java @@ -0,0 +1,29 @@ +package org.hjug.refactorfirst.report.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * One graph edge in the nested hierarchy, referencing the pre-resolved DOT node ids of its + * endpoints (class node ids in the class/cycle graphs, package node ids in the package graph). + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EdgeDTO { + + /** DOT node id of the edge source. */ + private String source; + + /** DOT node id of the edge target. */ + private String target; + + /** Edge weight (relationship count), rendered as the edge label. */ + private int weight; + + /** Whether the relationship was selected for removal to break cycles (red edge). */ + private boolean markedForRemoval; +} diff --git a/report/src/main/java/org/hjug/refactorfirst/report/model/GraphVisualDTO.java b/report/src/main/java/org/hjug/refactorfirst/report/model/GraphVisualDTO.java index 577c5d1f..66b20e31 100644 --- a/report/src/main/java/org/hjug/refactorfirst/report/model/GraphVisualDTO.java +++ b/report/src/main/java/org/hjug/refactorfirst/report/model/GraphVisualDTO.java @@ -15,6 +15,6 @@ public class GraphVisualDTO { private int relationshipCount; private int dotThreshold; private boolean dotThresholdExceeded; - private String dot; + private HierarchyDTO hierarchy; private boolean hasEdges; } diff --git a/report/src/main/java/org/hjug/refactorfirst/report/model/HierarchyDTO.java b/report/src/main/java/org/hjug/refactorfirst/report/model/HierarchyDTO.java new file mode 100644 index 00000000..4a071006 --- /dev/null +++ b/report/src/main/java/org/hjug/refactorfirst/report/model/HierarchyDTO.java @@ -0,0 +1,28 @@ +package org.hjug.refactorfirst.report.model; + +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Nested package/class hierarchy that replaces raw DOT in refactor-first.json and drives every + * nested package + class DOT graph. + * + *

Packages form a tree of clusters ({@link PackageNodeDTO}); classes ({@link ClassNodeDTO}) + * hang off their owning package; edges ({@link EdgeDTO}) reference the pre-resolved DOT node ids + * so renderers never re-derive id or label logic. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class HierarchyDTO { + + /** Root package clusters in sorted order, with single-child chains collapsed. */ + private List packages; + + /** Edges referencing the resolved DOT node ids, sorted by source then target. */ + private List edges; +} diff --git a/report/src/main/java/org/hjug/refactorfirst/report/model/LargestCycleDTO.java b/report/src/main/java/org/hjug/refactorfirst/report/model/LargestCycleDTO.java index e6c55cee..2e782018 100644 --- a/report/src/main/java/org/hjug/refactorfirst/report/model/LargestCycleDTO.java +++ b/report/src/main/java/org/hjug/refactorfirst/report/model/LargestCycleDTO.java @@ -17,7 +17,7 @@ public class LargestCycleDTO { private String cycleIdentifier; private int classCount; private int relationshipCount; - private String dot; + private HierarchyDTO hierarchy; private boolean dotThresholdExceeded; @Builder.Default diff --git a/report/src/main/java/org/hjug/refactorfirst/report/model/PackageNodeDTO.java b/report/src/main/java/org/hjug/refactorfirst/report/model/PackageNodeDTO.java new file mode 100644 index 00000000..f9d80bf9 --- /dev/null +++ b/report/src/main/java/org/hjug/refactorfirst/report/model/PackageNodeDTO.java @@ -0,0 +1,54 @@ +package org.hjug.refactorfirst.report.model; + +import java.util.ArrayList; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * One package in the nested hierarchy. + * + *

Every emitted package is a rectangle: a labelled cluster in the class/cycle graphs, or a + * rectangle node ({@code renderAsNode}) nested inside its ancestor clusters in the package + * graph. Packages flagged with {@code needsBreakUp} are rendered with a pink fill rather than + * the red previously used, distinguishing package-level breakup candidates from classes marked + * for removal. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PackageNodeDTO { + + /** Package name (FQN), or the synthetic {@code (default package)} bucket. */ + private String name; + + /** Pre-resolved DOT-safe cluster id ({@code cluster_}), stable and collision-free. */ + private String id; + + /** Pre-resolved DOT node id when this package renders as a node; {@code null} otherwise. */ + private String nodeId; + + /** Whether this package is a rectangle node in the package graph. */ + private boolean renderAsNode; + + /** Whether the package was selected for removal to break cycles (pink fill). */ + private boolean needsBreakUp; + + /** + * Repo-relative source directory of the package (with trailing slash), derived from + * the mapped class source paths; empty when no mapped class is known. Feeds the + * package graph's hyperlinks. + */ + private String path; + + /** Child package clusters, sorted by name, with single-child chains collapsed. */ + @Builder.Default + private List children = new ArrayList<>(); + + /** Classes owned by this package, sorted by FQN; empty in the package graph. */ + @Builder.Default + private List classes = new ArrayList<>(); +} diff --git a/report/src/main/resources/viewer/index.html b/report/src/main/resources/viewer/index.html index ef607130..6ccc812a 100644 --- a/report/src/main/resources/viewer/index.html +++ b/report/src/main/resources/viewer/index.html @@ -111,7 +111,16 @@

Loading RefactorFirst Report...

// Convert graphlib graph to graphology graph const graphologyGraph = new graphology.Graph(); + // graphlib-dot creates a node for every named subgraph: in the class + // map that is one cluster node per package, labelled with the package + // name. Drop subgraphs by their children, preserving class nodes such + // as cluster_Helper and the edges between the kept nodes. + const droppedClusters = new Set(); graphlibGraph.nodes().forEach(node => { + if (graphlibGraph.children(node).length > 0) { + droppedClusters.add(node); + return; + } const attrs = graphlibGraph.node(node); graphologyGraph.addNode(node, { label: attrs.label || node, @@ -121,6 +130,7 @@

Loading RefactorFirst Report...

}); graphlibGraph.edges().forEach(edge => { + if (droppedClusters.has(edge.v) || droppedClusters.has(edge.w)) return; const attrs = graphlibGraph.edge(edge); graphologyGraph.addEdge(edge.v, edge.w, { color: attrs.color, @@ -158,7 +168,14 @@

Loading RefactorFirst Report...

var nodes = []; var links = []; + // Drop subgraphs by their children, preserving class nodes such + // as cluster_Helper and the edges between the kept nodes. + var droppedClusters = new Set(); graphlibGraph.nodes().forEach(function (node) { + if (graphlibGraph.children(node).length > 0) { + droppedClusters.add(node); + return; + } var nodeData = graphlibGraph.node(node); nodes.push({ id: node, @@ -167,6 +184,7 @@

Loading RefactorFirst Report...

}); graphlibGraph.edges().forEach(function (edge) { + if (droppedClusters.has(edge.v) || droppedClusters.has(edge.w)) return; links.push({ source: edge.v, target: edge.w, @@ -332,6 +350,132 @@

Loading RefactorFirst Report...