@@ -43,6 +43,9 @@ public class ICodeMetricsProcessor {
4343
4444 /** Shared part between all i-Code metrics key. **/
4545 private static final String COMMON_METRICS_KEY_PART = ".MET." ;
46+ /** Define location in the code **/
47+ public static final String CLASS = "class" ;
48+ public static final String METHOD = "method" ;
4649
4750 /**
4851 * Private constructor because this class contains only static methods.
@@ -60,69 +63,68 @@ public static boolean isMetric(final String ruleId) {
6063 }
6164
6265 /**
63- * Save a measure in a SQ or CNES metric .
66+ * Save a measure in SonarQube from i-Code report format .
6467 *
6568 * @param context Context of the analysis containing services.
6669 * @param files Map containing files in SQ format.
67- * @param rule Measure considered like a rule in i-Code.
70+ * @param icodeMeasure Measure considered like a rule in i-Code.
6871 */
69- public static void saveMeasure (final SensorContext context , final Map <String , InputFile > files , final AnalysisRule rule ) {
72+ public static void saveMeasure (final SensorContext context , final Map <String , InputFile > files ,
73+ final AnalysisRule icodeMeasure ) {
7074
71- // Create a new measure from the scan context.
72- final NewMeasure <Integer > newMeasure = context .newMeasure ();
73- // i-Code rule id.
74- final String metricKey = rule .getAnalysisRuleId ();
7575 // Determine if a measure is relative to a file or a method.
76- final String metricScope = rule .getResult ().getResultTypePlace ();
77- // Component concerned by the measure.
78- final String metricComponent = rule .getResult ().getFileName ();
79- // Component concerned by the measure.
80- final String measureValue = rule .getResult ().getResultValue ();
81-
82- // Is true if the metric must be interpreted by the plugin.
83- boolean isCalculated = false ;
76+ final String metricScope = icodeMeasure .getResult ().getResultTypePlace ();
8477
85- // Local attribute to set
86- Metric <Integer > metric = null ;
87- InputComponent component = null ;
88- Integer value = null ;
89- if (metricScope .equals ("class" )) {
78+ if (metricScope .equals (CLASS )) {
79+ // Get i-Code rule id to test if issue must be saved here.
80+ final String metricKey = icodeMeasure .getAnalysisRuleId ();
9081 // Take SHELL / F77 / F90 ncloc into account
9182 if (metricKey .contains ("MET.LineOfCode" )) {
92- metric = CoreMetrics .NCLOC ;
93- component = files .getOrDefault (metricComponent , null );
94- value = Double .valueOf (measureValue ).intValue ();
95- isCalculated = true ;
83+ saveSonarQubeNewMeasure (context , files , CoreMetrics .NCLOC , icodeMeasure );
9684 }
9785 // Take SHELL / F77 / F90 number of comment lines into account
9886 else if (metricKey .contains ("MET.LineOfComment" )) {
99- metric = CoreMetrics .COMMENT_LINES ;
100- component = files .getOrDefault (metricComponent , null );
101- value = Double .valueOf (measureValue ).intValue ();
102- isCalculated = true ;
87+ saveSonarQubeNewMeasure (context , files , CoreMetrics .COMMENT_LINES , icodeMeasure );
10388 }
10489 // Take SHELL complexity into account
10590 else if (metricKey .contains ("SH.MET.ComplexitySimplified" )) {
106- metric = CoreMetrics .COMPLEXITY ;
107- component = files .getOrDefault (metricComponent , null );
108- value = Double .valueOf (measureValue ).intValue ();
109- isCalculated = true ;
91+ saveSonarQubeNewMeasure (context , files , CoreMetrics .COMPLEXITY , icodeMeasure );
11092 }
11193 }
11294
95+ }
96+
97+ /**
98+ * Save an issue or log a warning if the component is not found.
99+ *
100+ * @param context SonarQube context in which measure must be saved.
101+ * @param files All files visible by SonarQube.
102+ * @param sonarMetric The SonarQube metric in which the measure must be saved.
103+ * @param icodeMeasure The value of the i-Code measure.
104+ */
105+ protected static void saveSonarQubeNewMeasure (final SensorContext context , final Map <String , InputFile > files ,
106+ final Metric <Integer > sonarMetric , final AnalysisRule icodeMeasure ) {
107+
108+ // Component concerned by the measure.
109+ final String metricComponent = icodeMeasure .getResult ().getFileName ();
110+ // Component concerned by the measure.
111+ final String measureValue = icodeMeasure .getResult ().getResultValue ();
112+ // Retrieve the component/file on which the measure has been taken.
113+ final InputComponent component = files .getOrDefault (metricComponent , null );
114+ // i-Code takes measure as Double and SonarQube as Integer: just convert it.
115+ final int value = Double .valueOf (measureValue ).intValue ();
113116 // Finally save the measure if all value are filled.
114- if ( isCalculated ) {
115- if ( metric != null && value != null && component != null ) {
116- newMeasure . forMetric ( metric );
117- newMeasure .withValue ( value );
118- newMeasure .on ( component );
119- newMeasure .save ( );
120- } else {
121- LOGGER . warn ( String . format ( "Measure '%s' for '%s' is ignored on '%s'." ,
122- metricKey , metricScope , metricComponent ));
123- }
117+ if ( component != null ) {
118+ // Create a new measure from the scan context.
119+ final NewMeasure < Integer > newMeasure = context . newMeasure ( );
120+ newMeasure .forMetric ( sonarMetric );
121+ newMeasure .withValue ( value );
122+ newMeasure .on ( component );
123+ newMeasure . save ();
124+ } else {
125+ LOGGER . warn ( String . format ( "Measure '%s' for '%s' is ignored on '%s'." ,
126+ icodeMeasure . getAnalysisRuleId (), CLASS , metricComponent ));
124127 }
125-
126128 }
127129
128130 /**
@@ -142,7 +144,7 @@ public static void saveExtraMeasures(final SensorContext context, final Map<Stri
142144 for (final AnalysisRule rule : project .getAnalysisRules ()) {
143145 final String type = rule .getResult ().getResultTypePlace ();
144146 final String id = rule .getAnalysisRuleId ();
145- if (id .contains (COMMON_METRICS_KEY_PART ) && type .equals ("method" )) {
147+ if (id .contains (COMMON_METRICS_KEY_PART ) && type .equals (METHOD )) {
146148 final List <AnalysisRule > sub = measures .getOrDefault (id , new ArrayList <>());
147149 sub .add (rule );
148150 measures .put (id , sub );
@@ -173,9 +175,9 @@ public static void saveExtraMeasures(final SensorContext context, final Map<Stri
173175
174176 // Collect all measures on methods into specific list
175177 for (final CheckResult result : results ) {
176- final String type = Objects .isNull (result .getLocation ()) || result .getLocation ().isEmpty () ? "class" : "method" ;
178+ final String type = Objects .isNull (result .getLocation ()) || result .getLocation ().isEmpty () ? CLASS : METHOD ;
177179 final String id = result .getName ();
178- if (id .contains (COMMON_METRICS_KEY_PART ) && type .equals ("method" )) {
180+ if (id .contains (COMMON_METRICS_KEY_PART ) && type .equals (METHOD )) {
179181 final List <AnalysisRule > sub = measures .getOrDefault (id , new ArrayList <>());
180182 final AnalysisRule rule = new AnalysisRule (result );
181183 sub .add (rule );
@@ -320,71 +322,29 @@ private static void saveMeasure(final SensorContext context, final Map<String, I
320322 }
321323
322324 /**
323- * Save a measure in a SQ or CNES metric .
325+ * Save a measure in SonarQube from i-Code internal java model format .
324326 *
325- * @param sensorContext Context of the analysis containing services.
327+ * @param context Context of the analysis containing services.
326328 * @param result Measure considered like a rule in i-Code.
327329 */
328- public static void saveMeasure (final SensorContext sensorContext , final CheckResult result ) {
330+ public static void saveMeasure (final SensorContext context , final CheckResult result ) {
329331
330332 // Filesystem provided by SonarQube.
331- final FileSystem fileSystem = sensorContext .fileSystem ();
333+ final FileSystem fileSystem = context .fileSystem ();
332334 // Factory for SonarQube predicates.
333335 final FilePredicates predicates = fileSystem .predicates ();
334- // Create a new measure from the scan context.
335- final NewMeasure <Integer > newMeasure = sensorContext .newMeasure ();
336- // i-Code rule id.
337- final String metricKey = result .getName ();
338- // Determine if a measure is relative to a file or a method.
339- final String metricScope = Objects .isNull (result .getLocation ()) || result .getLocation ().isEmpty () ? "class" : "method" ;
340336 // Component concerned by the measure.
341337 final String metricComponent = result .getFile ().getPath ();
342- // Component concerned by the measure.
343- final String measureValue = String .valueOf (result .getValue ());
344338
345- // Is true if the metric must be interpreted by the plugin.
346- boolean isCalculated = false ;
339+ // Create a fake Map of input files to reuse function.
340+ final Map <String , InputFile > files = new HashMap <>();
341+ files .put (metricComponent , fileSystem .inputFile (predicates .hasPath (metricComponent )));
347342
348- // Local attribute to set
349- Metric <Integer > metric = null ;
350- InputComponent component = null ;
351- Integer value = null ;
352- if (metricScope .equals ("class" )) {
353- // Take SHELL / F77 / F90 ncloc into account
354- if (metricKey .contains ("MET.LineOfCode" )) {
355- metric = CoreMetrics .NCLOC ;
356- component = fileSystem .inputFile (predicates .hasPath (metricComponent ));
357- value = Double .valueOf (measureValue ).intValue ();
358- isCalculated = true ;
359- }
360- // Take SHELL / F77 / F90 number of comment lines into account
361- else if (metricKey .contains ("MET.LineOfComment" )) {
362- metric = CoreMetrics .COMMENT_LINES ;
363- component = fileSystem .inputFile (predicates .hasPath (metricComponent ));
364- value = Double .valueOf (measureValue ).intValue ();
365- isCalculated = true ;
366- }
367- // Take SHELL complexity into account
368- else if (metricKey .contains ("SH.MET.ComplexitySimplified" )) {
369- metric = CoreMetrics .COMPLEXITY ;
370- component = fileSystem .inputFile (predicates .hasPath (metricComponent ));
371- value = Double .valueOf (measureValue ).intValue ();
372- isCalculated = true ;
373- }
374- }
343+ // Create a fake AnalysisRule for reuse purpose.
344+ final AnalysisRule icodeMeasure = new AnalysisRule (result );
375345
376- // Finally save the measure if all value are filled.
377- if (isCalculated ) {
378- if (metric != null && value != null && component != null ) {
379- newMeasure .forMetric (metric );
380- newMeasure .withValue (value );
381- newMeasure .on (component );
382- newMeasure .save ();
383- } else {
384- LOGGER .warn (String .format ("Measure '%s' for '%s' is ignored on '%s'." ,
385- metricKey , metricScope , metricComponent ));
386- }
387- }
346+ // Call method for AnalysisRule saving.
347+ saveMeasure (context , files , icodeMeasure );
388348
389349 }
390350}
0 commit comments