Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion change-proneness-ranker/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.hjug.refactorfirst</groupId>
<artifactId>refactor-first</artifactId>
<version>0.5.1-SNAPSHOT</version>
<version>0.6.0-SNAPSHOT</version>
</parent>

<groupId>org.hjug.refactorfirst.changepronenessranker</groupId>
Expand Down
13 changes: 12 additions & 1 deletion circular-reference-detector/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.hjug.refactorfirst</groupId>
<artifactId>refactor-first</artifactId>
<version>0.5.1-SNAPSHOT</version>
<version>0.6.0-SNAPSHOT</version>
</parent>

<groupId>org.hjug.refactorfirst.circularreferencedetector</groupId>
Expand All @@ -13,6 +13,16 @@
<description>Tool to help detecting circular references by parsing a java project.</description>

<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-core</artifactId>
Expand All @@ -35,6 +45,7 @@
<version>5.9.0</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.extern.slf4j.Slf4j;
import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultDirectedWeightedGraph;
import org.jgrapht.graph.DefaultWeightedEdge;

@Slf4j
public class JavaProjectParser {

/**
Expand All @@ -37,6 +39,7 @@ public Graph<String, DefaultWeightedEdge> getClassReferences(String srcDirectory
filesStream
.filter(path -> path.getFileName().toString().endsWith(".java"))
.forEach(path -> {
log.info("Parsing {}", path);
List<String> types = getInstanceVarTypes(classNames, path.toFile());
types.addAll(getMethodArgumentTypes(classNames, path.toFile()));
if (!types.isEmpty()) {
Expand Down
2 changes: 1 addition & 1 deletion cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.hjug.refactorfirst</groupId>
<artifactId>refactor-first</artifactId>
<version>0.5.1-SNAPSHOT</version>
<version>0.6.0-SNAPSHOT</version>
</parent>

<packaging>jar</packaging>
Expand Down
2 changes: 1 addition & 1 deletion cost-benefit-calculator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.hjug.refactorfirst</groupId>
<artifactId>refactor-first</artifactId>
<version>0.5.1-SNAPSHOT</version>
<version>0.6.0-SNAPSHOT</version>
</parent>

<groupId>org.hjug.refactorfirst.costbenefitcalculator</groupId>
Expand Down
2 changes: 1 addition & 1 deletion coverage/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.hjug.refactorfirst</groupId>
<artifactId>refactor-first</artifactId>
<version>0.5.1-SNAPSHOT</version>
<version>0.6.0-SNAPSHOT</version>
</parent>

<artifactId>coverage</artifactId>
Expand Down
4 changes: 2 additions & 2 deletions effort-ranker/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.hjug.refactorfirst</groupId>
<artifactId>refactor-first</artifactId>
<version>0.5.1-SNAPSHOT</version>
<version>0.6.0-SNAPSHOT</version>
</parent>

<groupId>org.hjug.refactorfirst.effortranker</groupId>
Expand All @@ -20,7 +20,7 @@
<dependency>
<groupId>org.hjug.refactorfirst.testresources</groupId>
<artifactId>test-resources</artifactId>
<version>0.5.1-SNAPSHOT</version>
<version>0.6.0-SNAPSHOT</version>
</dependency>

<dependency>
Expand Down
4 changes: 2 additions & 2 deletions graph-data-generator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.hjug.refactorfirst</groupId>
<artifactId>refactor-first</artifactId>
<version>0.5.1-SNAPSHOT</version>
<version>0.6.0-SNAPSHOT</version>
</parent>

<groupId>org.hjug.refactorfirst.graphdatagenerator</groupId>
Expand All @@ -15,7 +15,7 @@
<dependency>
<groupId>org.hjug.refactorfirst.costbenefitcalculator</groupId>
<artifactId>cost-benefit-calculator</artifactId>
<version>0.5.1-SNAPSHOT</version>
<version>0.6.0-SNAPSHOT</version>
</dependency>
</dependencies>

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>org.hjug.refactorfirst</groupId>
<artifactId>refactor-first</artifactId>
<version>0.5.1-SNAPSHOT</version>
<version>0.6.0-SNAPSHOT</version>
<packaging>pom</packaging>

<url>https://github.com/refactorfirst/RefactorFirst</url>
Expand Down
2 changes: 1 addition & 1 deletion refactor-first-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.hjug.refactorfirst</groupId>
<artifactId>refactor-first</artifactId>
<version>0.5.1-SNAPSHOT</version>
<version>0.6.0-SNAPSHOT</version>
</parent>

<groupId>org.hjug.refactorfirst.plugin</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@ public String getDescription(Locale locale) {
+ " have the highest priority values.";
}

public final String[] cycleTableHeadings = {
"Cycle Name", "Priority", "Change Proneness Rank", "Class Count", "Relationship Count", "Minimum Cuts"
};

public final String[] classCycleTableHeadings = {"Classes", "Relationships"};

private Graph<String, DefaultWeightedEdge> classGraph;
Expand Down Expand Up @@ -164,6 +160,28 @@ public void executeReport(Locale locale) throws MavenReportException {

mainSink.unknown(script, new Object[] {HtmlMarkup.TAG_TYPE_START}, cboJavascript);
mainSink.unknown(script, new Object[] {HtmlMarkup.TAG_TYPE_END}, null);

SinkEventAttributeSet d3js = new SinkEventAttributeSet();
d3js.addAttribute(SinkEventAttributes.TYPE, "text/javascript");
d3js.addAttribute(SinkEventAttributes.SRC, "https://d3js.org/d3.v5.min.js");

mainSink.unknown(script, new Object[] {HtmlMarkup.TAG_TYPE_START}, d3js);
mainSink.unknown(script, new Object[] {HtmlMarkup.TAG_TYPE_END}, null);

SinkEventAttributeSet graphViz = new SinkEventAttributeSet();
graphViz.addAttribute(SinkEventAttributes.TYPE, "text/javascript");
graphViz.addAttribute(SinkEventAttributes.SRC, "https://unpkg.com/[email protected]/build/d3-graphviz.min.js");

mainSink.unknown(script, new Object[] {HtmlMarkup.TAG_TYPE_START}, graphViz);
mainSink.unknown(script, new Object[] {HtmlMarkup.TAG_TYPE_END}, null);

SinkEventAttributeSet wasm = new SinkEventAttributeSet();
wasm.addAttribute(SinkEventAttributes.TYPE, "text/javascript");
wasm.addAttribute(SinkEventAttributes.SRC, "https://unpkg.com/@hpcc-js/[email protected]/dist/index.min.js");

mainSink.unknown(script, new Object[] {HtmlMarkup.TAG_TYPE_START}, wasm);
mainSink.unknown(script, new Object[] {HtmlMarkup.TAG_TYPE_END}, null);

mainSink.head_();

mainSink.body();
Expand Down Expand Up @@ -472,12 +490,26 @@ private void renderCycles(
mainSink.section2_();
mainSink.division_();

mainSink.paragraph(alignCenter);
mainSink.text("Note: often only one minimum cut relationship needs to be removed");
mainSink.paragraph_();

mainSink.table();
mainSink.tableRows(new int[] {Sink.JUSTIFY_LEFT}, true);

// Content
// header row

String[] cycleTableHeadings;
if (showDetails) {
cycleTableHeadings = new String[] {
"Cycle Name", "Priority", "Change Proneness Rank", "Class Count", "Relationship Count", "Minimum Cuts"
};
} else {
cycleTableHeadings =
new String[] {"Cycle Name", "Priority", "Class Count", "Relationship Count", "Minimum Cuts"};
}

mainSink.tableRow();
for (String heading : cycleTableHeadings) {
drawTableHeaderCell(heading, mainSink);
Expand All @@ -492,15 +524,27 @@ private void renderCycles(
edgesToCut.append(minCutEdge + ":" + (int) classGraph.getEdgeWeight(minCutEdge));
}

// "Cycle Name", "Priority", "Change Proneness Rank", "Class Count", "Relationship Count", "Min Cuts"
String[] rankedCycleData = {
rankedCycle.getCycleName(),
rankedCycle.getPriority().toString(),
rankedCycle.getChangePronenessRank().toString(),
String.valueOf(rankedCycle.getCycleNodes().size()),
String.valueOf(rankedCycle.getEdgeSet().size()),
edgesToCut.toString()
};
String[] rankedCycleData;
if (showDetails) {
// "Cycle Name", "Priority", "Change Proneness Rank", "Class Count", "Relationship Count", "Min Cuts"
rankedCycleData = new String[] {
rankedCycle.getCycleName(),
rankedCycle.getPriority().toString(),
rankedCycle.getChangePronenessRank().toString(),
String.valueOf(rankedCycle.getCycleNodes().size()),
String.valueOf(rankedCycle.getEdgeSet().size()),
edgesToCut.toString()
};
} else {
// "Cycle Name", "Priority", "Class Count", "Relationship Count", "Min Cuts"
rankedCycleData = new String[] {
rankedCycle.getCycleName(),
rankedCycle.getPriority().toString(),
String.valueOf(rankedCycle.getCycleNodes().size()),
String.valueOf(rankedCycle.getEdgeSet().size()),
edgesToCut.toString()
};
}

for (String rowData : rankedCycleData) {
drawCycleTableCell(rowData, mainSink);
Expand All @@ -513,12 +557,11 @@ private void renderCycles(
mainSink.table_();

for (RankedCycle rankedCycle : rankedCycles) {
renderCycleTable(outputDirectory, mainSink, rankedCycle, formatter);
renderCycle(outputDirectory, mainSink, rankedCycle, formatter);
}
}

private void renderCycleTable(
String outputDirectory, Sink mainSink, RankedCycle cycle, DateTimeFormatter formatter) {
private void renderCycle(String outputDirectory, Sink mainSink, RankedCycle cycle, DateTimeFormatter formatter) {

mainSink.lineBreak();
mainSink.lineBreak();
Expand All @@ -537,7 +580,7 @@ private void renderCycleTable(
mainSink.section2_();
mainSink.division_();

renderCycleImage(cycle.getCycleName(), mainSink, outputDirectory);
renderCycleImage(classGraph, cycle, mainSink);

mainSink.division(alignCenter);
mainSink.bold();
Expand Down Expand Up @@ -580,25 +623,6 @@ private void renderCycleTable(
mainSink.table_();
}

public void renderCycleImage(String cycleName, Sink mainSink, String outputDirectory) {
SinkEventAttributeSet alignCenter = new SinkEventAttributeSet();
alignCenter.addAttribute(SinkEventAttributes.ALIGN, "center");
mainSink.division(alignCenter);

SinkEventAttributeSet imageAttributes = new SinkEventAttributeSet();
imageAttributes.addAttribute(SinkEventAttributes.TYPE, "img");
imageAttributes.addAttribute(SinkEventAttributes.SRC, "./refactorFirst/cycles/graph" + cycleName + ".png");
imageAttributes.addAttribute(SinkEventAttributes.WIDTH, 1000);
imageAttributes.addAttribute(SinkEventAttributes.HEIGHT, 1000);
imageAttributes.addAttribute(SinkEventAttributes.ALT, "Cycle " + cycleName);

mainSink.unknown("img", new Object[] {HtmlMarkup.TAG_TYPE_SIMPLE}, imageAttributes);

mainSink.division_();
mainSink.lineBreak();
mainSink.lineBreak();
}

private void renderLegend(Sink mainSink, String legendHeading, String xAxis) {
SinkEventAttributeSet width = new SinkEventAttributeSet();
width.addAttribute(SinkEventAttributes.STYLE, "width:350px");
Expand Down Expand Up @@ -809,4 +833,90 @@ void writeGCBOGchartJs(List<RankedDisharmony> rankedDisharmonies, int maxPriorit
log.error("Error writing CBO chart script file", e);
}
}

void renderCycleImage(Graph<String, DefaultWeightedEdge> classGraph, RankedCycle cycle, Sink mainSink) {

SinkEventAttributeSet graphDivAttrs = new SinkEventAttributeSet();
graphDivAttrs.addAttribute(SinkEventAttributes.ALIGN, "center");
graphDivAttrs.addAttribute(SinkEventAttributes.ID, cycle.getCycleName());
graphDivAttrs.addAttribute(SinkEventAttributes.STYLE, "border: thin solid black");

mainSink.division(graphDivAttrs);
mainSink.division_();

String dot = buildDot(classGraph, cycle);

StringBuilder d3chart = new StringBuilder();
d3chart.append("d3.select(\"#" + cycle.getCycleName() + "\")\n");
d3chart.append(".graphviz()\n");
d3chart.append(".width(screen.width - 300)\n");
d3chart.append(".height(screen.height)\n");
d3chart.append(".fit(true)\n");
d3chart.append(".renderDot(" + dot + ");\n");

SinkEventAttributeSet dotChartScript = new SinkEventAttributeSet();
dotChartScript.addAttribute(SinkEventAttributes.TYPE, "text/javascript");

String script = "script";
mainSink.unknown(script, new Object[] {HtmlMarkup.TAG_TYPE_START}, dotChartScript);

mainSink.rawText(d3chart.toString());
mainSink.unknown(script, new Object[] {HtmlMarkup.TAG_TYPE_END}, null);

SinkEventAttributeSet alignCenter = new SinkEventAttributeSet();
alignCenter.addAttribute(SinkEventAttributes.ALIGN, "center");

mainSink.paragraph(alignCenter);
mainSink.text("Red arrows represent relationship(s) to remove to decompose cycle");
mainSink.paragraph_();

mainSink.lineBreak();
mainSink.lineBreak();
}

String buildDot(Graph<String, DefaultWeightedEdge> classGraph, RankedCycle cycle) {
StringBuilder dot = new StringBuilder();

dot.append("'strict digraph G {\\n' +\n");

// render vertices
// e.g DownloadManager;
for (String vertex : cycle.getVertexSet()) {
dot.append("'");
dot.append(vertex);
dot.append(";\\n' +\n");
}

for (DefaultWeightedEdge edge : cycle.getEdgeSet()) {
// 'DownloadManager -> Download [ label="1" color="red" ];'

// render edge
String[] vertexes =
edge.toString().replace("(", "").replace(")", "").split(":");

String start = vertexes[0].trim();
String end = vertexes[1].trim();

dot.append("'");
dot.append(start);
dot.append(" -> ");
dot.append(end);

// render edge attributes
dot.append(" [ ");
dot.append("label = \"");
dot.append((int) classGraph.getEdgeWeight(edge));
dot.append("\"");

if (cycle.getMinCutEdges().contains(edge)) {
dot.append(" color = \"red\"");
}

dot.append(" ];\\n' +\n");
}

dot.append("'}'");

return dot.toString();
}
}
2 changes: 1 addition & 1 deletion report/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.hjug.refactorfirst</groupId>
<artifactId>refactor-first</artifactId>
<version>0.5.1-SNAPSHOT</version>
<version>0.6.0-SNAPSHOT</version>
</parent>

<groupId>org.hjug.refactorfirst.report</groupId>
Expand Down
Loading