forked from pica/ruby-sonar-plugin
-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathMetricfuComplexityYamlParserImpl.java
More file actions
executable file
·154 lines (123 loc) · 5.79 KB
/
MetricfuComplexityYamlParserImpl.java
File metadata and controls
executable file
·154 lines (123 loc) · 5.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package com.godaddy.sonar.ruby.metricfu;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;
import com.google.common.base.Throwables;
public class MetricfuComplexityYamlParserImpl implements
MetricfuComplexityYamlParser {
private Map<String, Object> metricfuResult;
private static final Logger LOG = LoggerFactory
.getLogger(MetricfuComplexityYamlParser.class);
@SuppressWarnings("unchecked")
public List<RubyFunction> parseFunctions(String fileNameFromModule, File resultsFile, String complexityType) throws IOException
{
// String fileString = FileUtils.readFileToString(resultsFile, "UTF-8");
InputStream resultsStream = new FileInputStream(resultsFile);
LOG.debug("MetricfuComplexityYamlParserImpl: Start start parse of metrics_fu YAML");
// remove ":hotspots:" section of the yaml so snakeyaml can parse it
// correctly, snakeyaml throws an error with that section intact
// Will remove if metric_fu metric filtering works for hotspots in the
// future
// Removing this as it seems to be working correctly with current versions of dependencies
// int hotSpotIndex = fileString.indexOf(":hotspots:");
// if (hotSpotIndex >= 0)
// {
// String stringToRemove = fileString.substring(hotSpotIndex, fileString.length());
// fileString = StringUtils.remove(fileString, stringToRemove);
// }
Yaml yaml = new Yaml();
try {
// metricfuResult = (Map<String, Object>) yaml.loadAs(fileString, Map.class);
if(metricfuResult == null) {
metricfuResult = new HashMap();
metricfuResult = (Map<String, Object>) yaml.load(resultsStream);
}
Map<String, Object> saikuroResult = (Map<String, Object>) metricfuResult.get(":saikuro");
Map<String, Object> caneResult = (Map<String, Object>) metricfuResult.get(":cane");
if ("Saikuro".equals(complexityType) && null != saikuroResult) {
return analyzeSaikuro(fileNameFromModule, metricfuResult, saikuroResult);
} else if ("Cane".equals(complexityType) && null != caneResult) {
return analyzeCane(fileNameFromModule, metricfuResult, caneResult);
} else {
LOG.warn("No data found for complexity type " + complexityType);
return new ArrayList<RubyFunction>();
}
} catch (Exception e) {
LOG.error(Throwables.getStackTraceAsString(e));
throw new IOException("Failure parsing YAML results", e);
}
}
private List<RubyFunction> analyzeSaikuro(String fileNameFromModule, Map<String, Object> metricfuResult,
Map<String, Object> saikuroResult) {
List<RubyFunction> rubyFunctionsForFile = new ArrayList<RubyFunction>();
Map<String, Object> fileInfoToWorkWith = new HashMap<String, Object>();
LOG.debug("MetricfuComplexityYamlParserImpl: parsing results from saikuro");
ArrayList<Map<String, Object>> saikuroFilesResult = (ArrayList<Map<String, Object>>) saikuroResult.get(":files");
for (Map<String, Object> fileInfo : saikuroFilesResult)
{
String fileNameFromResults = (String) fileInfo.get(":filename");
if (fileNameFromResults.contains(fileNameFromModule))
{
fileInfoToWorkWith = fileInfo;
break;
}
}
if (fileInfoToWorkWith.size() == 0)
{
// file has no methods returning empty function list
return new ArrayList<RubyFunction>();
}
ArrayList<Map<String, Object>> classesInfo = (ArrayList<Map<String, Object>>) fileInfoToWorkWith.get(":classes");
for (Map<String, Object> classInfo : classesInfo)
{
ArrayList<Map<String, Object>> methods = (ArrayList<Map<String, Object>>) classInfo.get(":methods");
for (Map<String, Object> method : methods)
{
RubyFunction rubyFunction = new RubyFunction();
rubyFunction.setName((String) method.get(":name"));
rubyFunction.setComplexity((Integer) method.get(":complexity"));
rubyFunction.setLine((Integer) method.get(":lines"));
rubyFunctionsForFile.add(rubyFunction);
}
}
return rubyFunctionsForFile;
}
private List<RubyFunction> analyzeCane(String fileNameFromModule, Map<String, Object> metricfuResult,
Map<String, Object> caneResult) {
List<RubyFunction> rubyFunctionsForFile = new ArrayList<RubyFunction>();
Map<String, Object> fileInfoToWorkWith = new HashMap<String, Object>();
LOG.debug("MetricfuComplexityYamlParserImpl: parsing results from cane");
Map<String, Object> caneViolationsResult = (Map<String, Object>) caneResult.get(":violations");
ArrayList<Map<String, Object>> caneAbcComplexityResult = (ArrayList<Map<String, Object>>) caneViolationsResult.get(":abc_complexity");
for (Map<String, Object> fileInfo : caneAbcComplexityResult)
{
String fileNameFromResults = (String) fileInfo.get(":file");
if (fileNameFromResults.contains(fileNameFromModule))
{
fileInfoToWorkWith = fileInfo;
break;
}
}
if (fileInfoToWorkWith.size() == 0)
{
// file has no methods returning empty function list
return new ArrayList<RubyFunction>();
}
RubyFunction rubyFunction = new RubyFunction();
LOG.debug("analyzeCane: fileInfoToWorkWith - " + fileInfoToWorkWith);
rubyFunction.setName((String) fileInfoToWorkWith.get(":method"));
rubyFunction.setComplexity(Integer.parseInt( (String)(fileInfoToWorkWith.get(":complexity"))));
rubyFunctionsForFile.add(rubyFunction);
return rubyFunctionsForFile;
}
}