001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2011 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * Sonar is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * Sonar is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public
017     * License along with Sonar; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019     */
020    package org.sonar.api.measures;
021    
022    import com.google.common.collect.Lists;
023    import org.apache.commons.lang.StringUtils;
024    import org.sonar.api.resources.Scopes;
025    import org.sonar.api.utils.SonarException;
026    
027    import java.lang.reflect.Field;
028    import java.util.List;
029    
030    /**
031     * @since 1.10
032     */
033    public final class CoreMetrics {
034    
035      private CoreMetrics() {
036        // only static stuff
037      }
038    
039      public static final String DOMAIN_SIZE = "Size";
040      public static final String DOMAIN_TESTS = "Tests";
041      public static final String DOMAIN_COMPLEXITY = "Complexity";
042      public static final String DOMAIN_DOCUMENTATION = "Documentation";
043      public static final String DOMAIN_RULES = "Rules";
044      public static final String DOMAIN_SCM = "SCM";
045    
046      /**
047       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
048       */
049      @Deprecated
050      public static final String DOMAIN_RULE_CATEGORIES = "Rule categories";
051    
052      public static final String DOMAIN_GENERAL = "General";
053      public static final String DOMAIN_DUPLICATION = "Duplication";
054      public static final String DOMAIN_DESIGN = "Design";
055    
056      public static final String LINES_KEY = "lines";
057      public static final Metric LINES = new Metric.Builder(LINES_KEY, "Lines", Metric.ValueType.INT)
058          .setDescription("Lines")
059          .setDirection(Metric.DIRECTION_WORST)
060          .setQualitative(false)
061          .setDomain(DOMAIN_SIZE)
062          .setFormula(new SumChildValuesFormula(false))
063          .create();
064    
065      public static final String GENERATED_LINES_KEY = "generated_lines";
066      public static final Metric GENERATED_LINES = new Metric.Builder(GENERATED_LINES_KEY, "Generated Lines", Metric.ValueType.INT)
067          .setDescription("Number of generated lines")
068          .setDirection(Metric.DIRECTION_WORST)
069          .setQualitative(false)
070          .setDomain(DOMAIN_SIZE)
071          .setBestValue(0.0)
072          .setOptimizedBestValue(true)
073          .setFormula(new SumChildValuesFormula(false))
074          .create();
075    
076      public static final String NCLOC_KEY = "ncloc";
077      public static final Metric NCLOC = new Metric.Builder(NCLOC_KEY, "Lines of code", Metric.ValueType.INT)
078          .setDescription("Non Commenting Lines of Code")
079          .setDirection(Metric.DIRECTION_WORST)
080          .setQualitative(false)
081          .setDomain(DOMAIN_SIZE)
082          .setFormula(new SumChildValuesFormula(false))
083          .create();
084    
085      public static final String GENERATED_NCLOC_KEY = "generated_ncloc";
086      public static final Metric GENERATED_NCLOC = new Metric.Builder(GENERATED_NCLOC_KEY, "Generated lines of code", Metric.ValueType.INT)
087          .setDescription("Generated non Commenting Lines of Code")
088          .setDirection(Metric.DIRECTION_WORST)
089          .setQualitative(false)
090          .setDomain(DOMAIN_SIZE)
091          .setBestValue(0.0)
092          .setOptimizedBestValue(true)
093          .setFormula(new SumChildValuesFormula(false))
094          .create();
095    
096      public static final String CLASSES_KEY = "classes";
097      public static final Metric CLASSES = new Metric.Builder(CLASSES_KEY, "Classes", Metric.ValueType.INT)
098          .setDescription("Classes")
099          .setDirection(Metric.DIRECTION_WORST)
100          .setQualitative(false)
101          .setDomain(DOMAIN_SIZE)
102          .setFormula(new SumChildValuesFormula(false))
103          .create();
104    
105      public static final String FILES_KEY = "files";
106      public static final Metric FILES = new Metric.Builder(FILES_KEY, "Files", Metric.ValueType.INT)
107          .setDescription("Number of files")
108          .setDirection(Metric.DIRECTION_WORST)
109          .setQualitative(false)
110          .setDomain(DOMAIN_SIZE)
111          .create();
112    
113      public static final String DIRECTORIES_KEY = "directories";
114      public static final Metric DIRECTORIES = new Metric.Builder(DIRECTORIES_KEY, "Directories", Metric.ValueType.INT)
115          .setDescription("Directories")
116          .setDirection(Metric.DIRECTION_WORST)
117          .setQualitative(false)
118          .setDomain(DOMAIN_SIZE)
119          .create();
120    
121      public static final String PACKAGES_KEY = "packages";
122      public static final Metric PACKAGES = new Metric.Builder(PACKAGES_KEY, "Packages", Metric.ValueType.INT)
123          .setDescription("Packages")
124          .setDirection(Metric.DIRECTION_WORST)
125          .setQualitative(false)
126          .setDomain(DOMAIN_SIZE)
127          .setFormula(new SumChildValuesFormula(false))
128          .create();
129    
130      public static final String FUNCTIONS_KEY = "functions";
131      public static final Metric FUNCTIONS = new Metric.Builder(FUNCTIONS_KEY, "Methods", Metric.ValueType.INT)
132          .setDescription("Methods")
133          .setDirection(Metric.DIRECTION_WORST)
134          .setQualitative(false)
135          .setDomain(DOMAIN_SIZE)
136          .setFormula(new SumChildValuesFormula(false))
137          .create();
138    
139      public static final String ACCESSORS_KEY = "accessors";
140      public static final Metric ACCESSORS = new Metric.Builder(ACCESSORS_KEY, "Accessors", Metric.ValueType.INT)
141          .setDescription("Accessors")
142          .setDirection(Metric.DIRECTION_WORST)
143          .setQualitative(false)
144          .setDomain(DOMAIN_SIZE)
145          .setFormula(new SumChildValuesFormula(false))
146          .create();
147    
148      public static final String PARAGRAPHS_KEY = "paragraphs";
149      public static final Metric PARAGRAPHS = new Metric.Builder(PARAGRAPHS_KEY, "Paragraphs", Metric.ValueType.INT)
150          .setDescription("Number of paragraphs")
151          .setDirection(Metric.DIRECTION_WORST)
152          .setQualitative(false)
153          .setDomain(DOMAIN_SIZE)
154          .setFormula(new SumChildValuesFormula(false))
155          .create();
156    
157      public static final String STATEMENTS_KEY = "statements";
158      public static final Metric STATEMENTS = new Metric.Builder(STATEMENTS_KEY, "Statements", Metric.ValueType.INT)
159          .setDescription("Number of statements")
160          .setDirection(Metric.DIRECTION_WORST)
161          .setQualitative(false)
162          .setDomain(DOMAIN_SIZE)
163          .setFormula(new SumChildValuesFormula(false))
164          .create();
165    
166      public static final String PUBLIC_API_KEY = "public_api";
167      public static final Metric PUBLIC_API = new Metric.Builder(PUBLIC_API_KEY, "Public API", Metric.ValueType.INT)
168          .setDescription("Public API")
169          .setDirection(Metric.DIRECTION_WORST)
170          .setQualitative(false)
171          .setDomain(DOMAIN_SIZE)
172          .setFormula(new SumChildValuesFormula(false))
173          .create();
174    
175    
176      //--------------------------------------------------------------------------------------------------------------------
177      //
178      // DOCUMENTATION
179      //
180      //--------------------------------------------------------------------------------------------------------------------
181    
182      public static final String COMMENT_LINES_KEY = "comment_lines";
183      public static final Metric COMMENT_LINES = new Metric.Builder(COMMENT_LINES_KEY, "Comment lines", Metric.ValueType.INT)
184          .setDescription("Number of comment lines")
185          .setDirection(Metric.DIRECTION_BETTER)
186          .setQualitative(false)
187          .setDomain(DOMAIN_DOCUMENTATION)
188          .setFormula(new SumChildValuesFormula(false))
189          .create();
190    
191      public static final String COMMENT_LINES_DENSITY_KEY = "comment_lines_density";
192      public static final Metric COMMENT_LINES_DENSITY = new Metric.Builder(COMMENT_LINES_DENSITY_KEY, "Comments (%)", Metric.ValueType.PERCENT)
193          .setDescription("Comments balanced by ncloc + comment lines")
194          .setDirection(Metric.DIRECTION_BETTER)
195          .setQualitative(true)
196          .setDomain(DOMAIN_DOCUMENTATION)
197          .create();
198    
199      public static final String COMMENT_BLANK_LINES_KEY = "comment_blank_lines";
200      public static final Metric COMMENT_BLANK_LINES = new Metric.Builder(COMMENT_BLANK_LINES_KEY, "Blank comments", Metric.ValueType.INT)
201          .setDescription("Comments that do not contain comments")
202          .setDirection(Metric.DIRECTION_WORST)
203          .setQualitative(false)
204          .setDomain(DOMAIN_DOCUMENTATION)
205          .setFormula(new SumChildValuesFormula(false))
206          .setBestValue(0.0)
207          .setOptimizedBestValue(true)
208          .create();
209    
210      public static final String PUBLIC_DOCUMENTED_API_DENSITY_KEY = "public_documented_api_density";
211      public static final Metric PUBLIC_DOCUMENTED_API_DENSITY = new Metric.Builder(PUBLIC_DOCUMENTED_API_DENSITY_KEY, "Public documented API (%)", Metric.ValueType.PERCENT)
212          .setDescription("Public documented classes and methods balanced by ncloc")
213          .setDirection(Metric.DIRECTION_BETTER)
214          .setQualitative(true)
215          .setDomain(DOMAIN_DOCUMENTATION)
216          .setWorstValue(0.0)
217          .setBestValue(100.0)
218          .setOptimizedBestValue(true)
219          .create();
220    
221      public static final String PUBLIC_UNDOCUMENTED_API_KEY = "public_undocumented_api";
222      public static final Metric PUBLIC_UNDOCUMENTED_API = new Metric.Builder(PUBLIC_UNDOCUMENTED_API_KEY, "Public undocumented API", Metric.ValueType.INT)
223          .setDescription("Public undocumented classes, methods and variables")
224          .setDirection(Metric.DIRECTION_WORST)
225          .setQualitative(true)
226          .setDomain(DOMAIN_DOCUMENTATION)
227          .setBestValue(0.0)
228          .setDirection(Metric.DIRECTION_WORST)
229          .setOptimizedBestValue(true)
230          .setFormula(new SumChildValuesFormula(false))
231          .create();
232    
233      public static final String COMMENTED_OUT_CODE_LINES_KEY = "commented_out_code_lines";
234      public static final Metric COMMENTED_OUT_CODE_LINES = new Metric.Builder(COMMENTED_OUT_CODE_LINES_KEY, "Commented LOCs", Metric.ValueType.INT)
235          .setDescription("Commented lines of code")
236          .setDirection(Metric.DIRECTION_WORST)
237          .setQualitative(true)
238          .setDomain(DOMAIN_DOCUMENTATION)
239          .setFormula(new SumChildValuesFormula(false))
240          .setBestValue(0.0)
241          .setOptimizedBestValue(true)
242          .create();
243    
244    
245      //--------------------------------------------------------------------------------------------------------------------
246      //
247      // COMPLEXITY
248      //
249      //--------------------------------------------------------------------------------------------------------------------
250    
251      public static final String COMPLEXITY_KEY = "complexity";
252      public static final Metric COMPLEXITY = new Metric.Builder(COMPLEXITY_KEY, "Complexity", Metric.ValueType.INT)
253          .setDescription("Cyclomatic complexity")
254          .setDirection(Metric.DIRECTION_WORST)
255          .setQualitative(false)
256          .setDomain(DOMAIN_COMPLEXITY)
257          .setFormula(new SumChildValuesFormula(false))
258          .create();
259    
260      public static final String CLASS_COMPLEXITY_KEY = "class_complexity";
261      public static final Metric CLASS_COMPLEXITY = new Metric.Builder(CLASS_COMPLEXITY_KEY, "Complexity /class", Metric.ValueType.FLOAT)
262          .setDescription("Complexity average by class")
263          .setDirection(Metric.DIRECTION_WORST)
264          .setQualitative(true)
265          .setDomain(DOMAIN_COMPLEXITY)
266          .setFormula(new AverageComplexityFormula(CoreMetrics.CLASSES))
267          .create();
268    
269      public static final String FUNCTION_COMPLEXITY_KEY = "function_complexity";
270      public static final Metric FUNCTION_COMPLEXITY = new Metric.Builder(FUNCTION_COMPLEXITY_KEY, "Complexity /method", Metric.ValueType.FLOAT)
271          .setDescription("Complexity average by method")
272          .setDirection(Metric.DIRECTION_WORST)
273          .setQualitative(true)
274          .setDomain(DOMAIN_COMPLEXITY)
275          .setFormula(new AverageComplexityFormula(CoreMetrics.FUNCTIONS))
276          .create();
277    
278      public static final String FILE_COMPLEXITY_KEY = "file_complexity";
279      public static final Metric FILE_COMPLEXITY = new Metric.Builder(FILE_COMPLEXITY_KEY, "Complexity /file", Metric.ValueType.FLOAT)
280          .setDescription("Complexity average by file")
281          .setDirection(Metric.DIRECTION_WORST)
282          .setQualitative(true)
283          .setDomain(DOMAIN_COMPLEXITY)
284          .setFormula(new AverageComplexityFormula(CoreMetrics.FILES))
285          .create();
286    
287      public static final String PARAGRAPH_COMPLEXITY_KEY = "paragraph_complexity";
288      public static final Metric PARAGRAPH_COMPLEXITY = new Metric.Builder(PARAGRAPH_COMPLEXITY_KEY, "Complexity /paragraph", Metric.ValueType.FLOAT)
289          .setDescription("Complexity average by paragraph")
290          .setDirection(Metric.DIRECTION_WORST)
291          .setQualitative(true)
292          .setDomain(DOMAIN_COMPLEXITY)
293          .setFormula(new AverageComplexityFormula(CoreMetrics.PARAGRAPHS))
294          .create();
295    
296      public static final String CLASS_COMPLEXITY_DISTRIBUTION_KEY = "class_complexity_distribution";
297      public static final Metric CLASS_COMPLEXITY_DISTRIBUTION = new Metric.Builder(CLASS_COMPLEXITY_DISTRIBUTION_KEY, "Classes distribution /complexity", Metric.ValueType.DISTRIB)
298          .setDescription("Classes distribution /complexity")
299          .setDirection(Metric.DIRECTION_NONE)
300          .setQualitative(true)
301          .setDomain(DOMAIN_COMPLEXITY)
302          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
303          .create();
304    
305      public static final String FUNCTION_COMPLEXITY_DISTRIBUTION_KEY = "function_complexity_distribution";
306      public static final Metric FUNCTION_COMPLEXITY_DISTRIBUTION = new Metric.Builder(FUNCTION_COMPLEXITY_DISTRIBUTION_KEY, "Functions distribution /complexity", Metric.ValueType.DISTRIB)
307          .setDescription("Functions distribution /complexity")
308          .setDirection(Metric.DIRECTION_NONE)
309          .setQualitative(true)
310          .setDomain(DOMAIN_COMPLEXITY)
311          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
312          .create();
313    
314      public static final String FILE_COMPLEXITY_DISTRIBUTION_KEY = "file_complexity_distribution";
315      public static final Metric FILE_COMPLEXITY_DISTRIBUTION = new Metric.Builder(FILE_COMPLEXITY_DISTRIBUTION_KEY, "Files distribution /complexity", Metric.ValueType.DISTRIB)
316          .setDescription("Files distribution /complexity")
317          .setDirection(Metric.DIRECTION_NONE)
318          .setQualitative(true)
319          .setDomain(DOMAIN_COMPLEXITY)
320          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
321          .create();
322    
323      public static final String PARAGRAPH_COMPLEXITY_DISTRIBUTION_KEY = "paragraph_complexity_distribution";
324      public static final Metric PARAGRAPH_COMPLEXITY_DISTRIBUTION = new Metric.Builder(PARAGRAPH_COMPLEXITY_DISTRIBUTION_KEY, "Paragraph distribution /complexity", Metric.ValueType.DISTRIB)
325          .setDescription("Paragraph distribution /complexity")
326          .setDirection(Metric.DIRECTION_NONE)
327          .setQualitative(true)
328          .setDomain(DOMAIN_COMPLEXITY)
329          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
330          .create();
331    
332      //--------------------------------------------------------------------------------------------------------------------
333      //
334      // UNIT TESTS
335      //
336      //--------------------------------------------------------------------------------------------------------------------
337    
338      public static final String TESTS_KEY = "tests";
339    
340      /**
341       * Value of measure for this metric can be saved from Sensor, taking into account following rules:
342       * <ul>
343       * <li>If tool (like Maven Surefire Plugin) has not been activated to run unit tests, then Sensor should not save anything. For example there is no such tool for COBOL.</li>
344       * <li>If tool has been activated, but there was no unit tests to run, then zero value should be saved for project.</li>
345       * <li>Non-zero value should be saved for resources representing tests. And Sonar provides default Decorator, which will decorate parent resources.</li>
346       * <li>Should include {@link #TEST_FAILURES} and {@link #TEST_ERRORS}, but should not include {@link #SKIPPED_TESTS}.</li>
347       * </ul>
348       */
349      public static final Metric TESTS = new Metric.Builder(TESTS_KEY, "Unit tests", Metric.ValueType.INT)
350          .setDescription("Number of unit tests")
351          .setDirection(Metric.DIRECTION_WORST)
352          .setQualitative(false)
353          .setDomain(DOMAIN_TESTS)
354          .create();
355    
356      public static final String TEST_EXECUTION_TIME_KEY = "test_execution_time";
357      public static final Metric TEST_EXECUTION_TIME = new Metric.Builder(TEST_EXECUTION_TIME_KEY, "Unit tests duration", Metric.ValueType.MILLISEC)
358          .setDescription("Execution duration of unit tests")
359          .setDirection(Metric.DIRECTION_WORST)
360          .setQualitative(false)
361          .setDomain(DOMAIN_TESTS)
362          .create();
363    
364      public static final String TEST_ERRORS_KEY = "test_errors";
365      public static final Metric TEST_ERRORS = new Metric.Builder(TEST_ERRORS_KEY, "Unit test errors", Metric.ValueType.INT)
366          .setDescription("Number of unit test errors")
367          .setDirection(Metric.DIRECTION_WORST)
368          .setQualitative(false)
369          .setDomain(DOMAIN_TESTS)
370          .setBestValue(0.0)
371          .setOptimizedBestValue(true)
372          .create();
373    
374      public static final String SKIPPED_TESTS_KEY = "skipped_tests";
375      public static final Metric SKIPPED_TESTS = new Metric.Builder(SKIPPED_TESTS_KEY, "Skipped unit tests", Metric.ValueType.INT)
376          .setDescription("Number of skipped unit tests")
377          .setDirection(Metric.DIRECTION_WORST)
378          .setQualitative(false)
379          .setDomain(DOMAIN_TESTS)
380          .setBestValue(0.0)
381          .setOptimizedBestValue(true)
382          .create();
383    
384      public static final String TEST_FAILURES_KEY = "test_failures";
385      public static final Metric TEST_FAILURES = new Metric.Builder(TEST_FAILURES_KEY, "Unit test failures", Metric.ValueType.INT)
386          .setDescription("Number of unit test failures")
387          .setDirection(Metric.DIRECTION_WORST)
388          .setQualitative(false)
389          .setDomain(DOMAIN_TESTS)
390          .setBestValue(0.0)
391          .setOptimizedBestValue(true)
392          .create();
393    
394      public static final String TEST_SUCCESS_DENSITY_KEY = "test_success_density";
395      public static final Metric TEST_SUCCESS_DENSITY = new Metric.Builder(TEST_SUCCESS_DENSITY_KEY, "Unit test success (%)", Metric.ValueType.PERCENT)
396          .setDescription("Density of successful unit tests")
397          .setDirection(Metric.DIRECTION_BETTER)
398          .setQualitative(true)
399          .setDomain(DOMAIN_TESTS)
400          .setWorstValue(0.0)
401          .setBestValue(100.0)
402          .setOptimizedBestValue(true)
403          .create();
404    
405      public static final String TEST_DATA_KEY = "test_data";
406      public static final Metric TEST_DATA = new Metric.Builder(TEST_DATA_KEY, "Unit tests details", Metric.ValueType.DATA)
407          .setDescription("Unit tests details")
408          .setDirection(Metric.DIRECTION_WORST)
409          .setDomain(DOMAIN_TESTS)
410          .create();
411    
412      public static final String COVERAGE_KEY = "coverage";
413      public static final Metric COVERAGE = new Metric.Builder(COVERAGE_KEY, "Coverage", Metric.ValueType.PERCENT)
414          .setDescription("Coverage by unit tests")
415          .setDirection(Metric.DIRECTION_BETTER)
416          .setQualitative(true)
417          .setDomain(DOMAIN_TESTS)
418          .setWorstValue(0.0)
419          .setBestValue(100.0)
420          .create();
421    
422      public static final String NEW_COVERAGE_KEY = "new_coverage";
423      public static final Metric NEW_COVERAGE = new Metric.Builder(NEW_COVERAGE_KEY, "New coverage", Metric.ValueType.PERCENT)
424          .setDescription("Coverage of new/changed code")
425          .setDirection(Metric.DIRECTION_BETTER)
426          .setQualitative(true)
427          .setDomain(DOMAIN_TESTS)
428          .setWorstValue(0.0)
429          .setBestValue(100.0)
430          .create();
431    
432      public static final String LINES_TO_COVER_KEY = "lines_to_cover";
433    
434      /**
435       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
436       */
437      public static final Metric LINES_TO_COVER = new Metric.Builder(LINES_TO_COVER_KEY, "Lines to cover", Metric.ValueType.INT)
438          .setDescription("Lines to cover")
439          .setDirection(Metric.DIRECTION_BETTER)
440          .setQualitative(false)
441          .setDomain(DOMAIN_TESTS)
442          .setFormula(new SumChildValuesFormula(false))
443          .setHidden(true)
444          .create();
445    
446      public static final String NEW_LINES_TO_COVER_KEY = "new_lines_to_cover";
447      public static final Metric NEW_LINES_TO_COVER = new Metric.Builder(NEW_LINES_TO_COVER_KEY, "New lines to cover", Metric.ValueType.INT)
448          .setDescription("New lines to cover")
449          .setDirection(Metric.DIRECTION_WORST)
450          .setQualitative(false)
451          .setDomain(DOMAIN_TESTS)
452          .setFormula(new SumChildValuesFormula(false))
453          .create();
454    
455      public static final String UNCOVERED_LINES_KEY = "uncovered_lines";
456    
457      /**
458       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
459       */
460      public static final Metric UNCOVERED_LINES = new Metric.Builder(UNCOVERED_LINES_KEY, "Uncovered lines", Metric.ValueType.INT)
461          .setDescription("Uncovered lines")
462          .setDirection(Metric.DIRECTION_WORST)
463          .setDomain(DOMAIN_TESTS)
464          .setFormula(new SumChildValuesFormula(false))
465          .setBestValue(0.0)
466          .create();
467    
468      public static final String NEW_UNCOVERED_LINES_KEY = "new_uncovered_lines";
469      public static final Metric NEW_UNCOVERED_LINES = new Metric.Builder(NEW_UNCOVERED_LINES_KEY, "New uncovered lines", Metric.ValueType.INT)
470          .setDescription("New uncovered lines")
471          .setDirection(Metric.DIRECTION_WORST)
472          .setDomain(DOMAIN_TESTS)
473          .setFormula(new SumChildValuesFormula(false))
474          .setBestValue(0.0)
475          .create();
476    
477      public static final String LINE_COVERAGE_KEY = "line_coverage";
478      public static final Metric LINE_COVERAGE = new Metric.Builder(LINE_COVERAGE_KEY, "Line coverage", Metric.ValueType.PERCENT)
479          .setDescription("Line coverage")
480          .setDirection(Metric.DIRECTION_BETTER)
481          .setQualitative(true)
482          .setDomain(DOMAIN_TESTS)
483          .setWorstValue(0.0)
484          .setBestValue(100.0)
485          .create();
486    
487      public static final String NEW_LINE_COVERAGE_KEY = "new_line_coverage";
488      public static final Metric NEW_LINE_COVERAGE = new Metric.Builder(NEW_LINE_COVERAGE_KEY, "New line coverage", Metric.ValueType.PERCENT)
489          .setDescription("Line coverage of added/changed code")
490          .setDirection(Metric.DIRECTION_BETTER)
491          .setQualitative(true)
492          .setWorstValue(0.0)
493          .setBestValue(100.0)
494          .setDomain(DOMAIN_TESTS)
495          .create();
496    
497      public static final String COVERAGE_LINE_HITS_DATA_KEY = "coverage_line_hits_data";
498    
499      /**
500       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
501       */
502      public static final Metric COVERAGE_LINE_HITS_DATA = new Metric.Builder(COVERAGE_LINE_HITS_DATA_KEY, "Coverage hits by line", Metric.ValueType.DATA)
503          .setDomain(DOMAIN_TESTS)
504          .create();
505    
506      public static final String CONDITIONS_TO_COVER_KEY = "conditions_to_cover";
507    
508      /**
509       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
510       */
511      public static final Metric CONDITIONS_TO_COVER = new Metric.Builder(CONDITIONS_TO_COVER_KEY, "Conditions to cover", Metric.ValueType.INT)
512          .setDescription("Conditions to cover")
513          .setDomain(DOMAIN_TESTS)
514          .setFormula(new SumChildValuesFormula(false))
515          .setHidden(true)
516          .create();
517    
518      public static final String NEW_CONDITIONS_TO_COVER_KEY = "new_conditions_to_cover";
519      public static final Metric NEW_CONDITIONS_TO_COVER = new Metric.Builder(NEW_CONDITIONS_TO_COVER_KEY, "New conditions to cover", Metric.ValueType.INT)
520          .setDescription("New conditions to cover")
521          .setDomain(DOMAIN_TESTS)
522          .setFormula(new SumChildValuesFormula(false))
523          .create();
524    
525      public static final String UNCOVERED_CONDITIONS_KEY = "uncovered_conditions";
526    
527      /**
528       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
529       */
530      public static final Metric UNCOVERED_CONDITIONS = new Metric.Builder(UNCOVERED_CONDITIONS_KEY, "Uncovered conditions", Metric.ValueType.INT)
531          .setDescription("Uncovered conditions")
532          .setDirection(Metric.DIRECTION_WORST)
533          .setDomain(DOMAIN_TESTS)
534          .setFormula(new SumChildValuesFormula(false))
535          .setBestValue(0.0)
536          .create();
537    
538      public static final String NEW_UNCOVERED_CONDITIONS_KEY = "new_uncovered_conditions";
539      public static final Metric NEW_UNCOVERED_CONDITIONS = new Metric.Builder(NEW_UNCOVERED_CONDITIONS_KEY, "New uncovered conditions", Metric.ValueType.INT)
540          .setDescription("New uncovered conditions")
541          .setDirection(Metric.DIRECTION_WORST)
542          .setDomain(DOMAIN_TESTS)
543          .setFormula(new SumChildValuesFormula(false))
544          .setBestValue(0.0)
545          .create();
546    
547      public static final String BRANCH_COVERAGE_KEY = "branch_coverage";
548      public static final Metric BRANCH_COVERAGE = new Metric.Builder(BRANCH_COVERAGE_KEY, "Branch coverage", Metric.ValueType.PERCENT)
549          .setDescription("Branch coverage")
550          .setDirection(Metric.DIRECTION_BETTER)
551          .setQualitative(true)
552          .setDomain(DOMAIN_TESTS)
553          .setWorstValue(0.0)
554          .setBestValue(100.0)
555          .create();
556    
557      public static final String NEW_BRANCH_COVERAGE_KEY = "new_branch_coverage";
558      public static final Metric NEW_BRANCH_COVERAGE = new Metric.Builder(NEW_BRANCH_COVERAGE_KEY, "New branch coverage", Metric.ValueType.PERCENT)
559          .setDescription("Branch coverage of new/changed code")
560          .setDirection(Metric.DIRECTION_BETTER)
561          .setQualitative(true)
562          .setDomain(DOMAIN_TESTS)
563          .setWorstValue(0.0)
564          .setBestValue(100.0)
565          .create();
566    
567      /**
568       * @deprecated in 2.7. Replaced by {@link #CONDITIONS_BY_LINE_KEY} and {@link #COVERED_CONDITIONS_BY_LINE_KEY}
569       */
570      @Deprecated
571      public static final String BRANCH_COVERAGE_HITS_DATA_KEY = "branch_coverage_hits_data";
572    
573      /**
574       * @deprecated in 2.7. Replaced by metrics {@link #CONDITIONS_BY_LINE} and {@link #COVERED_CONDITIONS_BY_LINE}
575       */
576      @Deprecated
577      public static final Metric BRANCH_COVERAGE_HITS_DATA = new Metric.Builder(BRANCH_COVERAGE_HITS_DATA_KEY, "Branch coverage hits", Metric.ValueType.DATA)
578          .setDomain(DOMAIN_TESTS)
579          .create();
580    
581      public static final String CONDITIONS_BY_LINE_KEY = "conditions_by_line";
582    
583      /**
584       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
585       *
586       * @since 2.7
587       */
588      public static final Metric CONDITIONS_BY_LINE = new Metric.Builder(CONDITIONS_BY_LINE_KEY, "Conditions by line", Metric.ValueType.DATA)
589          .setDomain(DOMAIN_TESTS)
590          .create();
591    
592      public static final String COVERED_CONDITIONS_BY_LINE_KEY = "covered_conditions_by_line";
593    
594      /**
595       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
596       *
597       * @since 2.7
598       */
599      public static final Metric COVERED_CONDITIONS_BY_LINE = new Metric.Builder(COVERED_CONDITIONS_BY_LINE_KEY, "Covered conditions by line", Metric.ValueType.DATA)
600          .setDomain(DOMAIN_TESTS)
601          .create();
602    
603    
604      //--------------------------------------------------------------------------------------------------------------------
605      //
606      // DUPLICATIONS
607      //
608      //--------------------------------------------------------------------------------------------------------------------
609    
610      public static final String DUPLICATED_LINES_KEY = "duplicated_lines";
611      public static final Metric DUPLICATED_LINES = new Metric.Builder(DUPLICATED_LINES_KEY, "Duplicated lines", Metric.ValueType.INT)
612          .setDescription("Duplicated lines")
613          .setDirection(Metric.DIRECTION_WORST)
614          .setDomain(DOMAIN_DUPLICATION)
615          .setBestValue(0.0)
616          .setOptimizedBestValue(true)
617          .create();
618    
619      public static final String DUPLICATED_BLOCKS_KEY = "duplicated_blocks";
620      public static final Metric DUPLICATED_BLOCKS = new Metric.Builder(DUPLICATED_BLOCKS_KEY, "Duplicated blocks", Metric.ValueType.INT)
621          .setDescription("Duplicated blocks")
622          .setDirection(Metric.DIRECTION_WORST)
623          .setDomain(DOMAIN_DUPLICATION)
624          .setBestValue(0.0)
625          .setOptimizedBestValue(true)
626          .create();
627    
628      public static final String DUPLICATED_FILES_KEY = "duplicated_files";
629      public static final Metric DUPLICATED_FILES = new Metric.Builder(DUPLICATED_FILES_KEY, "Duplicated files", Metric.ValueType.INT)
630          .setDescription("Duplicated files")
631          .setDirection(Metric.DIRECTION_WORST)
632          .setQualitative(true)
633          .setDomain(DOMAIN_DUPLICATION)
634          .setBestValue(0.0)
635          .setOptimizedBestValue(true)
636          .create();
637    
638      public static final String DUPLICATED_LINES_DENSITY_KEY = "duplicated_lines_density";
639      public static final Metric DUPLICATED_LINES_DENSITY = new Metric.Builder(DUPLICATED_LINES_DENSITY_KEY, "Duplicated lines (%)", Metric.ValueType.PERCENT)
640          .setDescription("Duplicated lines balanced by statements")
641          .setDirection(Metric.DIRECTION_WORST)
642          .setQualitative(true)
643          .setDomain(DOMAIN_DUPLICATION)
644          .setWorstValue(50.0)
645          .setBestValue(0.0)
646          .setOptimizedBestValue(true)
647          .create();
648    
649      public static final String DUPLICATIONS_DATA_KEY = "duplications_data";
650      public static final Metric DUPLICATIONS_DATA = new Metric.Builder(DUPLICATIONS_DATA_KEY, "Duplications details", Metric.ValueType.DATA)
651          .setDescription("Duplications details")
652          .setDirection(Metric.DIRECTION_NONE)
653          .setQualitative(false)
654          .setDomain(DOMAIN_DUPLICATION)
655          .create();
656    
657    
658      //--------------------------------------------------------------------------------------------------------------------
659      //
660      // CODING RULES
661      //
662      //--------------------------------------------------------------------------------------------------------------------
663      /**
664       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
665       */
666      @Deprecated
667      public static final String USABILITY_KEY = "usability";
668    
669      /**
670       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
671       */
672      @Deprecated
673      public static final Metric USABILITY = new Metric(USABILITY_KEY, "Usability", "Usability", Metric.ValueType.PERCENT,
674          Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
675    
676      /**
677       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
678       */
679      @Deprecated
680      public static final String RELIABILITY_KEY = "reliability";
681    
682      /**
683       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
684       */
685      @Deprecated
686      public static final Metric RELIABILITY = new Metric(RELIABILITY_KEY, "Reliability", "Reliability", Metric.ValueType.PERCENT,
687          Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
688    
689      /**
690       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
691       */
692      @Deprecated
693      public static final String EFFICIENCY_KEY = "efficiency";
694    
695      /**
696       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
697       */
698      @Deprecated
699      public static final Metric EFFICIENCY = new Metric(EFFICIENCY_KEY, "Efficiency", "Efficiency", Metric.ValueType.PERCENT,
700          Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
701    
702      /**
703       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
704       */
705      @Deprecated
706      public static final String PORTABILITY_KEY = "portability";
707    
708      /**
709       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
710       */
711      @Deprecated
712      public static final Metric PORTABILITY = new Metric(PORTABILITY_KEY, "Portability", "Portability", Metric.ValueType.PERCENT,
713          Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
714    
715      /**
716       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
717       */
718      @Deprecated
719      public static final String MAINTAINABILITY_KEY = "maintainability";
720    
721      /**
722       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
723       */
724      @Deprecated
725      public static final Metric MAINTAINABILITY = new Metric.Builder(MAINTAINABILITY_KEY, "Maintainability", Metric.ValueType.PERCENT)
726          .setDescription("Maintainability")
727          .setDirection(Metric.DIRECTION_BETTER)
728          .setQualitative(true)
729          .setDomain(DOMAIN_RULE_CATEGORIES)
730          .setBestValue(100.0)
731          .setOptimizedBestValue(true)
732          .create();
733    
734      public static final String WEIGHTED_VIOLATIONS_KEY = "weighted_violations";
735      public static final Metric WEIGHTED_VIOLATIONS = new Metric.Builder(WEIGHTED_VIOLATIONS_KEY, "Weighted violations", Metric.ValueType.INT)
736          .setDescription("Weighted Violations")
737          .setDirection(Metric.DIRECTION_WORST)
738          .setQualitative(true)
739          .setDomain(DOMAIN_RULES)
740          .setHidden(true)
741          .create();
742    
743      public static final String VIOLATIONS_DENSITY_KEY = "violations_density";
744      public static final Metric VIOLATIONS_DENSITY = new Metric.Builder(VIOLATIONS_DENSITY_KEY, "Rules compliance", Metric.ValueType.PERCENT)
745          .setDescription("Rules compliance")
746          .setDirection(Metric.DIRECTION_BETTER)
747          .setQualitative(true)
748          .setDomain(DOMAIN_RULES)
749          .create();
750    
751      public static final String VIOLATIONS_KEY = "violations";
752      public static final Metric VIOLATIONS = new Metric.Builder(VIOLATIONS_KEY, "Violations", Metric.ValueType.INT)
753          .setDescription("Violations")
754          .setDirection(Metric.DIRECTION_WORST)
755          .setQualitative(true)
756          .setDomain(DOMAIN_RULES)
757          .setBestValue(0.0)
758          .setOptimizedBestValue(true)
759          .create();
760    
761      public static final String BLOCKER_VIOLATIONS_KEY = "blocker_violations";
762      public static final Metric BLOCKER_VIOLATIONS = new Metric.Builder(BLOCKER_VIOLATIONS_KEY, "Blocker violations", Metric.ValueType.INT)
763          .setDescription("Blocker violations")
764          .setDirection(Metric.DIRECTION_WORST)
765          .setQualitative(true)
766          .setDomain(DOMAIN_RULES)
767          .setBestValue(0.0)
768          .setOptimizedBestValue(true)
769          .create();
770    
771      public static final String CRITICAL_VIOLATIONS_KEY = "critical_violations";
772      public static final Metric CRITICAL_VIOLATIONS = new Metric.Builder(CRITICAL_VIOLATIONS_KEY, "Critical violations", Metric.ValueType.INT)
773          .setDescription("Critical violations")
774          .setDirection(Metric.DIRECTION_WORST)
775          .setQualitative(true)
776          .setDomain(DOMAIN_RULES)
777          .setBestValue(0.0)
778          .setOptimizedBestValue(true)
779          .create();
780    
781      public static final String MAJOR_VIOLATIONS_KEY = "major_violations";
782      public static final Metric MAJOR_VIOLATIONS = new Metric.Builder(MAJOR_VIOLATIONS_KEY, "Major violations", Metric.ValueType.INT)
783          .setDescription("Major violations")
784          .setDirection(Metric.DIRECTION_WORST)
785          .setQualitative(true)
786          .setDomain(DOMAIN_RULES)
787          .setBestValue(0.0)
788          .setOptimizedBestValue(true)
789          .create();
790    
791      public static final String MINOR_VIOLATIONS_KEY = "minor_violations";
792      public static final Metric MINOR_VIOLATIONS = new Metric.Builder(MINOR_VIOLATIONS_KEY, "Minor violations", Metric.ValueType.INT)
793          .setDescription("Minor violations")
794          .setDirection(Metric.DIRECTION_WORST)
795          .setQualitative(true)
796          .setDomain(DOMAIN_RULES)
797          .setBestValue(0.0)
798          .setOptimizedBestValue(true)
799          .create();
800    
801      public static final String INFO_VIOLATIONS_KEY = "info_violations";
802      public static final Metric INFO_VIOLATIONS = new Metric.Builder(INFO_VIOLATIONS_KEY, "Info violations", Metric.ValueType.INT)
803          .setDescription("Info violations")
804          .setDirection(Metric.DIRECTION_WORST)
805          .setQualitative(true)
806          .setDomain(DOMAIN_RULES)
807          .setBestValue(0.0)
808          .setOptimizedBestValue(true)
809          .create();
810    
811      public static final String NEW_VIOLATIONS_KEY = "new_violations";
812      public static final Metric NEW_VIOLATIONS = new Metric.Builder(NEW_VIOLATIONS_KEY, "New Violations", Metric.ValueType.INT)
813          .setDescription("New Violations")
814          .setDirection(Metric.DIRECTION_WORST)
815          .setQualitative(true)
816          .setDomain(DOMAIN_RULES)
817          .setBestValue(0.0)
818          .setOptimizedBestValue(true)
819          .create();
820    
821      public static final String NEW_BLOCKER_VIOLATIONS_KEY = "new_blocker_violations";
822      public static final Metric NEW_BLOCKER_VIOLATIONS = new Metric.Builder(NEW_BLOCKER_VIOLATIONS_KEY, "New Blocker violations", Metric.ValueType.INT)
823          .setDescription("New Blocker violations")
824          .setDirection(Metric.DIRECTION_WORST)
825          .setQualitative(true)
826          .setDomain(DOMAIN_RULES)
827          .setBestValue(0.0)
828          .setOptimizedBestValue(true)
829          .create();
830    
831      public static final String NEW_CRITICAL_VIOLATIONS_KEY = "new_critical_violations";
832      public static final Metric NEW_CRITICAL_VIOLATIONS = new Metric.Builder(NEW_CRITICAL_VIOLATIONS_KEY, "New Critical violations", Metric.ValueType.INT)
833          .setDescription("New Critical violations")
834          .setDirection(Metric.DIRECTION_WORST)
835          .setQualitative(true)
836          .setDomain(DOMAIN_RULES)
837          .setBestValue(0.0)
838          .setOptimizedBestValue(true)
839          .create();
840    
841      public static final String NEW_MAJOR_VIOLATIONS_KEY = "new_major_violations";
842      public static final Metric NEW_MAJOR_VIOLATIONS = new Metric.Builder(NEW_MAJOR_VIOLATIONS_KEY, "New Major violations", Metric.ValueType.INT)
843          .setDescription("New Major violations")
844          .setDirection(Metric.DIRECTION_WORST)
845          .setQualitative(true)
846          .setDomain(DOMAIN_RULES)
847          .setBestValue(0.0)
848          .setOptimizedBestValue(true)
849          .create();
850    
851      public static final String NEW_MINOR_VIOLATIONS_KEY = "new_minor_violations";
852      public static final Metric NEW_MINOR_VIOLATIONS = new Metric.Builder(NEW_MINOR_VIOLATIONS_KEY, "New Minor violations", Metric.ValueType.INT)
853          .setDescription("New Minor violations")
854          .setDirection(Metric.DIRECTION_WORST)
855          .setQualitative(true)
856          .setDomain(DOMAIN_RULES)
857          .setBestValue(0.0)
858          .setOptimizedBestValue(true)
859          .create();
860    
861      public static final String NEW_INFO_VIOLATIONS_KEY = "new_info_violations";
862      public static final Metric NEW_INFO_VIOLATIONS = new Metric.Builder(NEW_INFO_VIOLATIONS_KEY, "New Info violations", Metric.ValueType.INT)
863          .setDescription("New Info violations")
864          .setDirection(Metric.DIRECTION_WORST)
865          .setQualitative(true)
866          .setDomain(DOMAIN_RULES)
867          .setBestValue(0.0)
868          .setOptimizedBestValue(true)
869          .create();
870    
871    
872      //--------------------------------------------------------------------------------------------------------------------
873      //
874      // DESIGN
875      //
876      //--------------------------------------------------------------------------------------------------------------------
877    
878      public static final String ABSTRACTNESS_KEY = "abstractness";
879      public static final Metric ABSTRACTNESS = new Metric.Builder(ABSTRACTNESS_KEY, "Abstractness", Metric.ValueType.PERCENT)
880          .setDescription("Abstractness")
881          .setDirection(Metric.DIRECTION_NONE)
882          .setQualitative(false)
883          .setDomain(DOMAIN_DESIGN)
884          .create();
885    
886      public static final String INSTABILITY_KEY = "instability";
887      public static final Metric INSTABILITY = new Metric.Builder(INSTABILITY_KEY, "Instability", Metric.ValueType.PERCENT)
888          .setDescription("Instability")
889          .setDirection(Metric.DIRECTION_NONE)
890          .setQualitative(false)
891          .setDomain(DOMAIN_DESIGN)
892          .create();
893    
894      public static final String DISTANCE_KEY = "distance";
895      public static final Metric DISTANCE = new Metric.Builder(DISTANCE_KEY, "Distance", Metric.ValueType.FLOAT)
896          .setDescription("Distance")
897          .setDirection(Metric.DIRECTION_NONE)
898          .setQualitative(false)
899          .setDomain(DOMAIN_DESIGN)
900          .create();
901    
902      public static final String DEPTH_IN_TREE_KEY = "dit";
903      public static final Metric DEPTH_IN_TREE = new Metric.Builder(DEPTH_IN_TREE_KEY, "Depth in Tree", Metric.ValueType.INT)
904          .setDescription("Depth in Inheritance Tree")
905          .setDirection(Metric.DIRECTION_NONE)
906          .setQualitative(false)
907          .setDomain(DOMAIN_DESIGN)
908          .create();
909    
910      public static final String NUMBER_OF_CHILDREN_KEY = "noc";
911      public static final Metric NUMBER_OF_CHILDREN = new Metric.Builder(NUMBER_OF_CHILDREN_KEY, "Number of Children", Metric.ValueType.INT)
912          .setDescription("Number of Children")
913          .setDirection(Metric.DIRECTION_NONE)
914          .setQualitative(false)
915          .setDomain(DOMAIN_DESIGN)
916          .create();
917    
918      public static final String RFC_KEY = "rfc";
919      public static final Metric RFC = new Metric.Builder(RFC_KEY, "RFC", Metric.ValueType.INT)
920          .setDescription("Response for Class")
921          .setDirection(Metric.DIRECTION_WORST)
922          .setQualitative(false)
923          .setDomain(DOMAIN_DESIGN)
924          .setFormula(new WeightedMeanAggregationFormula(CoreMetrics.FILES, false))
925          .create();
926    
927      public static final String RFC_DISTRIBUTION_KEY = "rfc_distribution";
928      public static final Metric RFC_DISTRIBUTION = new Metric.Builder(RFC_DISTRIBUTION_KEY, "Class distribution /RFC", Metric.ValueType.DISTRIB)
929          .setDescription("Class distribution /RFC")
930          .setDirection(Metric.DIRECTION_NONE)
931          .setQualitative(true)
932          .setDomain(DOMAIN_DESIGN)
933          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
934          .create();
935    
936      public static final String LCOM4_KEY = "lcom4";
937      public static final Metric LCOM4 = new Metric.Builder(LCOM4_KEY, "LCOM4", Metric.ValueType.FLOAT)
938          .setDescription("Lack of Cohesion of Methods")
939          .setDirection(Metric.DIRECTION_WORST)
940          .setQualitative(true)
941          .setDomain(DOMAIN_DESIGN)
942          .setBestValue(1.0)
943          .setFormula(new WeightedMeanAggregationFormula(CoreMetrics.FILES, false))
944          .create();
945    
946      public static final String LCOM4_BLOCKS_KEY = "lcom4_blocks";
947      public static final Metric LCOM4_BLOCKS = new Metric.Builder(LCOM4_BLOCKS_KEY, "LCOM4 blocks", Metric.ValueType.DATA)
948          .setDescription("LCOM4 blocks")
949          .setDirection(Metric.DIRECTION_NONE)
950          .setQualitative(false)
951          .setDomain(DOMAIN_DESIGN)
952          .setHidden(true)
953          .create();
954    
955      public static final String LCOM4_DISTRIBUTION_KEY = "lcom4_distribution";
956      public static final Metric LCOM4_DISTRIBUTION = new Metric.Builder(LCOM4_DISTRIBUTION_KEY, "Class distribution /LCOM4", Metric.ValueType.DISTRIB)
957          .setDescription("Class distribution /LCOM4")
958          .setDirection(Metric.DIRECTION_NONE)
959          .setQualitative(true)
960          .setDomain(DOMAIN_DESIGN)
961          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
962          .create();
963    
964      public static final String SUSPECT_LCOM4_DENSITY_KEY = "suspect_lcom4_density";
965      public static final Metric SUSPECT_LCOM4_DENSITY = new Metric.Builder(SUSPECT_LCOM4_DENSITY_KEY, "Suspect LCOM4 density", Metric.ValueType.PERCENT)
966          .setDescription("Density of classes having LCOM4>1")
967          .setDirection(Metric.DIRECTION_WORST)
968          .setQualitative(true)
969          .setDomain(DOMAIN_DESIGN)
970          .create();
971    
972      public static final String AFFERENT_COUPLINGS_KEY = "ca";
973      public static final Metric AFFERENT_COUPLINGS = new Metric.Builder(AFFERENT_COUPLINGS_KEY, "Afferent couplings", Metric.ValueType.INT)
974          .setDescription("Afferent couplings")
975          .setDirection(Metric.DIRECTION_WORST)
976          .setQualitative(false)
977          .setDomain(DOMAIN_DESIGN)
978          .create();
979    
980      public static final String EFFERENT_COUPLINGS_KEY = "ce";
981      public static final Metric EFFERENT_COUPLINGS = new Metric.Builder(EFFERENT_COUPLINGS_KEY, "Efferent couplings", Metric.ValueType.INT)
982          .setDescription("Efferent couplings")
983          .setDirection(Metric.DIRECTION_WORST)
984          .setQualitative(false)
985          .setDomain(DOMAIN_DESIGN)
986          .create();
987    
988      public static final String DEPENDENCY_MATRIX_KEY = "dsm";
989      public static final Metric DEPENDENCY_MATRIX = new Metric.Builder(DEPENDENCY_MATRIX_KEY, "Dependency Matrix", Metric.ValueType.DATA)
990          .setDescription("Dependency Matrix")
991          .setDirection(Metric.DIRECTION_NONE)
992          .setQualitative(false)
993          .setDomain(DOMAIN_DESIGN)
994          .create();
995    
996      public static final String PACKAGE_CYCLES_KEY = "package_cycles";
997      public static final Metric PACKAGE_CYCLES = new Metric.Builder(PACKAGE_CYCLES_KEY, "Package cycles", Metric.ValueType.INT)
998          .setDescription("Package cycles")
999          .setDirection(Metric.DIRECTION_WORST)
1000          .setQualitative(true)
1001          .setDomain(DOMAIN_DESIGN)
1002          .setFormula(new SumChildValuesFormula(false))
1003          .create();
1004    
1005      public static final String PACKAGE_TANGLE_INDEX_KEY = "package_tangle_index";
1006      public static final Metric PACKAGE_TANGLE_INDEX = new Metric.Builder(PACKAGE_TANGLE_INDEX_KEY, "Package tangle index", Metric.ValueType.PERCENT)
1007          .setDescription("Package tangle index")
1008          .setDirection(Metric.DIRECTION_WORST)
1009          .setQualitative(true)
1010          .setDomain(DOMAIN_DESIGN)
1011          .create();
1012    
1013      public static final String PACKAGE_TANGLES_KEY = "package_tangles";
1014      public static final Metric PACKAGE_TANGLES = new Metric.Builder(PACKAGE_TANGLES_KEY, "File dependencies to cut", Metric.ValueType.INT)
1015          .setDescription("File dependencies to cut")
1016          .setDirection(Metric.DIRECTION_WORST)
1017          .setQualitative(false)
1018          .setDomain(DOMAIN_DESIGN)
1019          .setFormula(new SumChildValuesFormula(false))
1020          .create();
1021    
1022      public static final String PACKAGE_FEEDBACK_EDGES_KEY = "package_feedback_edges";
1023      public static final Metric PACKAGE_FEEDBACK_EDGES = new Metric.Builder(PACKAGE_FEEDBACK_EDGES_KEY, "Package dependencies to cut", Metric.ValueType.INT)
1024          .setDescription("Package dependencies to cut")
1025          .setDirection(Metric.DIRECTION_WORST)
1026          .setQualitative(false)
1027          .setDomain(DOMAIN_DESIGN)
1028          .setFormula(new SumChildValuesFormula(false))
1029          .create();
1030    
1031      public static final String PACKAGE_EDGES_WEIGHT_KEY = "package_edges_weight";
1032      public static final Metric PACKAGE_EDGES_WEIGHT = new Metric.Builder(PACKAGE_EDGES_WEIGHT_KEY, "Package edges weight", Metric.ValueType.INT)
1033          .setDescription("Package edges weight")
1034          .setDirection(Metric.DIRECTION_BETTER)
1035          .setQualitative(false)
1036          .setDomain(DOMAIN_DESIGN)
1037          .setFormula(new SumChildValuesFormula(false))
1038          .setHidden(true)
1039          .create();
1040    
1041      public static final String FILE_CYCLES_KEY = "file_cycles";
1042      public static final Metric FILE_CYCLES = new Metric.Builder(FILE_CYCLES_KEY, "File cycles", Metric.ValueType.INT)
1043          .setDescription("File cycles")
1044          .setDirection(Metric.DIRECTION_WORST)
1045          .setQualitative(true)
1046          .setDomain(DOMAIN_DESIGN)
1047          .setHidden(true)
1048          .create();
1049    
1050      public static final String FILE_TANGLE_INDEX_KEY = "file_tangle_index";
1051      public static final Metric FILE_TANGLE_INDEX = new Metric.Builder(FILE_TANGLE_INDEX_KEY, "File tangle index", Metric.ValueType.PERCENT)
1052          .setDescription("File tangle index")
1053          .setDirection(Metric.DIRECTION_WORST)
1054          .setQualitative(true)
1055          .setDomain(DOMAIN_DESIGN)
1056          .setHidden(true)
1057          .create();
1058    
1059      public static final String FILE_TANGLES_KEY = "file_tangles";
1060      public static final Metric FILE_TANGLES = new Metric.Builder(FILE_TANGLES_KEY, "File tangles", Metric.ValueType.INT)
1061          .setDescription("Files tangles")
1062          .setDirection(Metric.DIRECTION_WORST)
1063          .setQualitative(false)
1064          .setDomain(DOMAIN_DESIGN)
1065          .setHidden(true)
1066          .create();
1067    
1068      public static final String FILE_FEEDBACK_EDGES_KEY = "file_feedback_edges";
1069      public static final Metric FILE_FEEDBACK_EDGES = new Metric.Builder(FILE_FEEDBACK_EDGES_KEY, "Suspect file dependencies", Metric.ValueType.INT)
1070          .setDescription("Suspect file dependencies")
1071          .setDirection(Metric.DIRECTION_WORST)
1072          .setQualitative(false)
1073          .setDomain(DOMAIN_DESIGN)
1074          .setHidden(true)
1075          .create();
1076    
1077      public static final String FILE_EDGES_WEIGHT_KEY = "file_edges_weight";
1078      public static final Metric FILE_EDGES_WEIGHT = new Metric.Builder(FILE_EDGES_WEIGHT_KEY, "File edges weight", Metric.ValueType.INT)
1079          .setDescription("File edges weight")
1080          .setDirection(Metric.DIRECTION_BETTER)
1081          .setQualitative(false)
1082          .setDomain(DOMAIN_DESIGN)
1083          .setHidden(true)
1084          .create();
1085    
1086    
1087      //--------------------------------------------------------------------------------------------------------------------
1088      //
1089      // SCM
1090      // These metrics are computed by the SCM Activity plugin, since version 1.2.
1091      //
1092      //--------------------------------------------------------------------------------------------------------------------
1093    
1094      public static final String SCM_COMMITS_KEY = "commits";
1095      public static final Metric SCM_COMMITS = new Metric.Builder(SCM_COMMITS_KEY, "Commits", Metric.ValueType.INT)
1096          .setDomain(DOMAIN_SCM)
1097          .create();
1098    
1099      public static final String SCM_LAST_COMMIT_DATE_KEY = "last_commit_date";
1100      public static final Metric SCM_LAST_COMMIT_DATE = new Metric.Builder(SCM_LAST_COMMIT_DATE_KEY, "Last commit", Metric.ValueType.STRING /* TODO: move to date */)
1101          .setDomain(DOMAIN_SCM)
1102          .create();
1103    
1104      public static final String SCM_REVISION_KEY = "revision";
1105      public static final Metric SCM_REVISION = new Metric.Builder(SCM_REVISION_KEY, "Revision", Metric.ValueType.STRING)
1106          .setDomain(DOMAIN_SCM)
1107          .setHidden(true)
1108          .create();
1109    
1110      public static final String SCM_AUTHORS_BY_LINE_KEY = "authors_by_line";
1111      public static final Metric SCM_AUTHORS_BY_LINE = new Metric.Builder(SCM_AUTHORS_BY_LINE_KEY, "Authors by line", Metric.ValueType.DATA)
1112          .setDomain(DOMAIN_SCM)
1113          .create();
1114    
1115      public static final String SCM_REVISIONS_BY_LINE_KEY = "revisions_by_line";
1116      public static final Metric SCM_REVISIONS_BY_LINE = new Metric.Builder(SCM_REVISIONS_BY_LINE_KEY, "Revisions by line", Metric.ValueType.DATA)
1117          .setDomain(DOMAIN_SCM)
1118          .create();
1119    
1120      public static final String SCM_LAST_COMMIT_DATETIMES_BY_LINE_KEY = "last_commit_datetimes_by_line";
1121      public static final Metric SCM_LAST_COMMIT_DATETIMES_BY_LINE = new Metric.Builder(SCM_LAST_COMMIT_DATETIMES_BY_LINE_KEY, "Last commit dates by line", Metric.ValueType.DATA)
1122          .setDomain(DOMAIN_SCM)
1123          .create();
1124    
1125    
1126      //--------------------------------------------------------------------------------------------------------------------
1127      //
1128      // OTHERS
1129      //
1130      //--------------------------------------------------------------------------------------------------------------------
1131      public static final String ALERT_STATUS_KEY = "alert_status";
1132      public static final Metric ALERT_STATUS = new Metric.Builder(ALERT_STATUS_KEY, "Alert", Metric.ValueType.LEVEL)
1133          .setDescription("Alert")
1134          .setDirection(Metric.DIRECTION_BETTER)
1135          .setQualitative(true)
1136          .setDomain(DOMAIN_GENERAL)
1137          .create();
1138    
1139    
1140      public static final String PROFILE_KEY = "profile";
1141      public static final Metric PROFILE = new Metric.Builder(PROFILE_KEY, "Profile", Metric.ValueType.DATA)
1142          .setDescription("Selected quality profile")
1143          .setDomain(DOMAIN_GENERAL)
1144          .create();
1145    
1146      public static final String PROFILE_VERSION_KEY = "profile_version";
1147      public static final Metric PROFILE_VERSION = new Metric.Builder(PROFILE_VERSION_KEY, "Profile version", Metric.ValueType.INT)
1148          .setDescription("Selected quality profile version")
1149          .setQualitative(false)
1150          .setDomain(DOMAIN_GENERAL)
1151          .create();
1152    
1153      public static List<Metric> metrics = Lists.newLinkedList();
1154    
1155      public static List<Metric> getMetrics() {
1156        if (metrics.isEmpty()) {
1157          for (Field field : CoreMetrics.class.getFields()) {
1158            if (Metric.class.isAssignableFrom(field.getType())) {
1159              try {
1160                Metric metric = (Metric) field.get(null);
1161                if (!StringUtils.equals(metric.getDomain(), DOMAIN_RULE_CATEGORIES)) {
1162                  metrics.add(metric);
1163                }
1164              } catch (IllegalAccessException e) {
1165                throw new SonarException("can not load metrics from " + CoreMetrics.class.getSimpleName(), e);
1166              }
1167            }
1168          }
1169        }
1170        return metrics;
1171      }
1172    }