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_INTEGRATION_TESTS = "Integration Tests";
042      public static final String DOMAIN_COMPLEXITY = "Complexity";
043      public static final String DOMAIN_DOCUMENTATION = "Documentation";
044      public static final String DOMAIN_RULES = "Rules";
045      public static final String DOMAIN_SCM = "SCM";
046    
047      /**
048       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
049       */
050      @Deprecated
051      public static final String DOMAIN_RULE_CATEGORIES = "Rule categories";
052    
053      public static final String DOMAIN_GENERAL = "General";
054      public static final String DOMAIN_DUPLICATION = "Duplication";
055      public static final String DOMAIN_DESIGN = "Design";
056    
057      public static final String LINES_KEY = "lines";
058      public static final Metric LINES = new Metric.Builder(LINES_KEY, "Lines", Metric.ValueType.INT)
059        .setDescription("Lines")
060        .setDirection(Metric.DIRECTION_WORST)
061        .setQualitative(false)
062        .setDomain(DOMAIN_SIZE)
063        .setFormula(new SumChildValuesFormula(false))
064        .create();
065    
066      public static final String GENERATED_LINES_KEY = "generated_lines";
067      public static final Metric GENERATED_LINES = new Metric.Builder(GENERATED_LINES_KEY, "Generated Lines", Metric.ValueType.INT)
068        .setDescription("Number of generated lines")
069        .setDirection(Metric.DIRECTION_WORST)
070        .setQualitative(false)
071        .setDomain(DOMAIN_SIZE)
072        .setBestValue(0.0)
073        .setOptimizedBestValue(true)
074        .setFormula(new SumChildValuesFormula(false))
075        .create();
076    
077      public static final String NCLOC_KEY = "ncloc";
078      public static final Metric NCLOC = new Metric.Builder(NCLOC_KEY, "Lines of code", Metric.ValueType.INT)
079        .setDescription("Non Commenting Lines of Code")
080        .setDirection(Metric.DIRECTION_WORST)
081        .setQualitative(false)
082        .setDomain(DOMAIN_SIZE)
083        .setFormula(new SumChildValuesFormula(false))
084        .create();
085    
086      public static final String GENERATED_NCLOC_KEY = "generated_ncloc";
087      public static final Metric GENERATED_NCLOC = new Metric.Builder(GENERATED_NCLOC_KEY, "Generated lines of code", Metric.ValueType.INT)
088        .setDescription("Generated non Commenting Lines of Code")
089        .setDirection(Metric.DIRECTION_WORST)
090        .setQualitative(false)
091        .setDomain(DOMAIN_SIZE)
092        .setBestValue(0.0)
093        .setOptimizedBestValue(true)
094        .setFormula(new SumChildValuesFormula(false))
095        .create();
096    
097      public static final String CLASSES_KEY = "classes";
098      public static final Metric CLASSES = new Metric.Builder(CLASSES_KEY, "Classes", Metric.ValueType.INT)
099        .setDescription("Classes")
100        .setDirection(Metric.DIRECTION_WORST)
101        .setQualitative(false)
102        .setDomain(DOMAIN_SIZE)
103        .setFormula(new SumChildValuesFormula(false))
104        .create();
105    
106      public static final String FILES_KEY = "files";
107      public static final Metric FILES = new Metric.Builder(FILES_KEY, "Files", Metric.ValueType.INT)
108        .setDescription("Number of files")
109        .setDirection(Metric.DIRECTION_WORST)
110        .setQualitative(false)
111        .setDomain(DOMAIN_SIZE)
112        .create();
113    
114      public static final String DIRECTORIES_KEY = "directories";
115      public static final Metric DIRECTORIES = new Metric.Builder(DIRECTORIES_KEY, "Directories", Metric.ValueType.INT)
116        .setDescription("Directories")
117        .setDirection(Metric.DIRECTION_WORST)
118        .setQualitative(false)
119        .setDomain(DOMAIN_SIZE)
120        .create();
121    
122      public static final String PACKAGES_KEY = "packages";
123      public static final Metric PACKAGES = new Metric.Builder(PACKAGES_KEY, "Packages", Metric.ValueType.INT)
124        .setDescription("Packages")
125        .setDirection(Metric.DIRECTION_WORST)
126        .setQualitative(false)
127        .setDomain(DOMAIN_SIZE)
128        .setFormula(new SumChildValuesFormula(false))
129        .create();
130    
131      public static final String FUNCTIONS_KEY = "functions";
132      public static final Metric FUNCTIONS = new Metric.Builder(FUNCTIONS_KEY, "Methods", Metric.ValueType.INT)
133        .setDescription("Methods")
134        .setDirection(Metric.DIRECTION_WORST)
135        .setQualitative(false)
136        .setDomain(DOMAIN_SIZE)
137        .setFormula(new SumChildValuesFormula(false))
138        .create();
139    
140      public static final String ACCESSORS_KEY = "accessors";
141      public static final Metric ACCESSORS = new Metric.Builder(ACCESSORS_KEY, "Accessors", Metric.ValueType.INT)
142        .setDescription("Accessors")
143        .setDirection(Metric.DIRECTION_WORST)
144        .setQualitative(false)
145        .setDomain(DOMAIN_SIZE)
146        .setFormula(new SumChildValuesFormula(false))
147        .create();
148    
149      public static final String PARAGRAPHS_KEY = "paragraphs";
150      public static final Metric PARAGRAPHS = new Metric.Builder(PARAGRAPHS_KEY, "Paragraphs", Metric.ValueType.INT)
151        .setDescription("Number of paragraphs")
152        .setDirection(Metric.DIRECTION_WORST)
153        .setQualitative(false)
154        .setDomain(DOMAIN_SIZE)
155        .setFormula(new SumChildValuesFormula(false))
156        .create();
157    
158      public static final String STATEMENTS_KEY = "statements";
159      public static final Metric STATEMENTS = new Metric.Builder(STATEMENTS_KEY, "Statements", Metric.ValueType.INT)
160        .setDescription("Number of statements")
161        .setDirection(Metric.DIRECTION_WORST)
162        .setQualitative(false)
163        .setDomain(DOMAIN_SIZE)
164        .setFormula(new SumChildValuesFormula(false))
165        .create();
166    
167      public static final String PUBLIC_API_KEY = "public_api";
168      public static final Metric PUBLIC_API = new Metric.Builder(PUBLIC_API_KEY, "Public API", Metric.ValueType.INT)
169        .setDescription("Public API")
170        .setDirection(Metric.DIRECTION_WORST)
171        .setQualitative(false)
172        .setDomain(DOMAIN_SIZE)
173        .setFormula(new SumChildValuesFormula(false))
174        .create();
175    
176    
177      //--------------------------------------------------------------------------------------------------------------------
178      //
179      // DOCUMENTATION
180      //
181      //--------------------------------------------------------------------------------------------------------------------
182    
183      public static final String COMMENT_LINES_KEY = "comment_lines";
184      public static final Metric COMMENT_LINES = new Metric.Builder(COMMENT_LINES_KEY, "Comment lines", Metric.ValueType.INT)
185        .setDescription("Number of comment lines")
186        .setDirection(Metric.DIRECTION_BETTER)
187        .setQualitative(false)
188        .setDomain(DOMAIN_DOCUMENTATION)
189        .setFormula(new SumChildValuesFormula(false))
190        .create();
191    
192      public static final String COMMENT_LINES_DENSITY_KEY = "comment_lines_density";
193      public static final Metric COMMENT_LINES_DENSITY = new Metric.Builder(COMMENT_LINES_DENSITY_KEY, "Comments (%)", Metric.ValueType.PERCENT)
194        .setDescription("Comments balanced by ncloc + comment lines")
195        .setDirection(Metric.DIRECTION_BETTER)
196        .setQualitative(true)
197        .setDomain(DOMAIN_DOCUMENTATION)
198        .create();
199    
200      public static final String COMMENT_BLANK_LINES_KEY = "comment_blank_lines";
201      public static final Metric COMMENT_BLANK_LINES = new Metric.Builder(COMMENT_BLANK_LINES_KEY, "Blank comments", Metric.ValueType.INT)
202        .setDescription("Comments that do not contain comments")
203        .setDirection(Metric.DIRECTION_WORST)
204        .setQualitative(false)
205        .setDomain(DOMAIN_DOCUMENTATION)
206        .setFormula(new SumChildValuesFormula(false))
207        .setBestValue(0.0)
208        .setOptimizedBestValue(true)
209        .create();
210    
211      public static final String PUBLIC_DOCUMENTED_API_DENSITY_KEY = "public_documented_api_density";
212      public static final Metric PUBLIC_DOCUMENTED_API_DENSITY = new Metric.Builder(PUBLIC_DOCUMENTED_API_DENSITY_KEY, "Public documented API (%)", Metric.ValueType.PERCENT)
213        .setDescription("Public documented classes and methods balanced by ncloc")
214        .setDirection(Metric.DIRECTION_BETTER)
215        .setQualitative(true)
216        .setDomain(DOMAIN_DOCUMENTATION)
217        .setWorstValue(0.0)
218        .setBestValue(100.0)
219        .setOptimizedBestValue(true)
220        .create();
221    
222      public static final String PUBLIC_UNDOCUMENTED_API_KEY = "public_undocumented_api";
223      public static final Metric PUBLIC_UNDOCUMENTED_API = new Metric.Builder(PUBLIC_UNDOCUMENTED_API_KEY, "Public undocumented API", Metric.ValueType.INT)
224        .setDescription("Public undocumented classes, methods and variables")
225        .setDirection(Metric.DIRECTION_WORST)
226        .setQualitative(true)
227        .setDomain(DOMAIN_DOCUMENTATION)
228        .setBestValue(0.0)
229        .setDirection(Metric.DIRECTION_WORST)
230        .setOptimizedBestValue(true)
231        .setFormula(new SumChildValuesFormula(false))
232        .create();
233    
234      public static final String COMMENTED_OUT_CODE_LINES_KEY = "commented_out_code_lines";
235      public static final Metric COMMENTED_OUT_CODE_LINES = new Metric.Builder(COMMENTED_OUT_CODE_LINES_KEY, "Commented-out LOC", Metric.ValueType.INT)
236        .setDescription("Commented lines of code")
237        .setDirection(Metric.DIRECTION_WORST)
238        .setQualitative(true)
239        .setDomain(DOMAIN_DOCUMENTATION)
240        .setFormula(new SumChildValuesFormula(false))
241        .setBestValue(0.0)
242        .setOptimizedBestValue(true)
243        .create();
244    
245    
246      //--------------------------------------------------------------------------------------------------------------------
247      //
248      // COMPLEXITY
249      //
250      //--------------------------------------------------------------------------------------------------------------------
251    
252      public static final String COMPLEXITY_KEY = "complexity";
253      public static final Metric COMPLEXITY = new Metric.Builder(COMPLEXITY_KEY, "Complexity", Metric.ValueType.INT)
254        .setDescription("Cyclomatic complexity")
255        .setDirection(Metric.DIRECTION_WORST)
256        .setQualitative(false)
257        .setDomain(DOMAIN_COMPLEXITY)
258        .setFormula(new SumChildValuesFormula(false))
259        .create();
260    
261      public static final String CLASS_COMPLEXITY_KEY = "class_complexity";
262      public static final Metric CLASS_COMPLEXITY = new Metric.Builder(CLASS_COMPLEXITY_KEY, "Complexity /class", Metric.ValueType.FLOAT)
263        .setDescription("Complexity average by class")
264        .setDirection(Metric.DIRECTION_WORST)
265        .setQualitative(true)
266        .setDomain(DOMAIN_COMPLEXITY)
267        .setFormula(new AverageComplexityFormula(CoreMetrics.CLASSES))
268        .create();
269    
270      public static final String FUNCTION_COMPLEXITY_KEY = "function_complexity";
271      public static final Metric FUNCTION_COMPLEXITY = new Metric.Builder(FUNCTION_COMPLEXITY_KEY, "Complexity /method", Metric.ValueType.FLOAT)
272        .setDescription("Complexity average by method")
273        .setDirection(Metric.DIRECTION_WORST)
274        .setQualitative(true)
275        .setDomain(DOMAIN_COMPLEXITY)
276        .setFormula(new AverageComplexityFormula(CoreMetrics.FUNCTIONS))
277        .create();
278    
279      public static final String FILE_COMPLEXITY_KEY = "file_complexity";
280      public static final Metric FILE_COMPLEXITY = new Metric.Builder(FILE_COMPLEXITY_KEY, "Complexity /file", Metric.ValueType.FLOAT)
281        .setDescription("Complexity average by file")
282        .setDirection(Metric.DIRECTION_WORST)
283        .setQualitative(true)
284        .setDomain(DOMAIN_COMPLEXITY)
285        .setFormula(new AverageComplexityFormula(CoreMetrics.FILES))
286        .create();
287    
288      public static final String PARAGRAPH_COMPLEXITY_KEY = "paragraph_complexity";
289      public static final Metric PARAGRAPH_COMPLEXITY = new Metric.Builder(PARAGRAPH_COMPLEXITY_KEY, "Complexity /paragraph", Metric.ValueType.FLOAT)
290        .setDescription("Complexity average by paragraph")
291        .setDirection(Metric.DIRECTION_WORST)
292        .setQualitative(true)
293        .setDomain(DOMAIN_COMPLEXITY)
294        .setFormula(new AverageComplexityFormula(CoreMetrics.PARAGRAPHS))
295        .create();
296    
297      public static final String CLASS_COMPLEXITY_DISTRIBUTION_KEY = "class_complexity_distribution";
298      public static final Metric CLASS_COMPLEXITY_DISTRIBUTION = new Metric.Builder(CLASS_COMPLEXITY_DISTRIBUTION_KEY, "Classes distribution /complexity", Metric.ValueType.DISTRIB)
299        .setDescription("Classes distribution /complexity")
300        .setDirection(Metric.DIRECTION_NONE)
301        .setQualitative(true)
302        .setDomain(DOMAIN_COMPLEXITY)
303        .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
304        .create();
305    
306      public static final String FUNCTION_COMPLEXITY_DISTRIBUTION_KEY = "function_complexity_distribution";
307      public static final Metric FUNCTION_COMPLEXITY_DISTRIBUTION = new Metric.Builder(FUNCTION_COMPLEXITY_DISTRIBUTION_KEY, "Functions distribution /complexity", Metric.ValueType.DISTRIB)
308        .setDescription("Functions distribution /complexity")
309        .setDirection(Metric.DIRECTION_NONE)
310        .setQualitative(true)
311        .setDomain(DOMAIN_COMPLEXITY)
312        .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
313        .create();
314    
315      public static final String FILE_COMPLEXITY_DISTRIBUTION_KEY = "file_complexity_distribution";
316      public static final Metric FILE_COMPLEXITY_DISTRIBUTION = new Metric.Builder(FILE_COMPLEXITY_DISTRIBUTION_KEY, "Files distribution /complexity", Metric.ValueType.DISTRIB)
317        .setDescription("Files distribution /complexity")
318        .setDirection(Metric.DIRECTION_NONE)
319        .setQualitative(true)
320        .setDomain(DOMAIN_COMPLEXITY)
321        .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
322        .create();
323    
324      public static final String PARAGRAPH_COMPLEXITY_DISTRIBUTION_KEY = "paragraph_complexity_distribution";
325      public static final Metric PARAGRAPH_COMPLEXITY_DISTRIBUTION = new Metric.Builder(PARAGRAPH_COMPLEXITY_DISTRIBUTION_KEY, "Paragraph distribution /complexity", Metric.ValueType.DISTRIB)
326        .setDescription("Paragraph distribution /complexity")
327        .setDirection(Metric.DIRECTION_NONE)
328        .setQualitative(true)
329        .setDomain(DOMAIN_COMPLEXITY)
330        .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
331        .create();
332    
333      //--------------------------------------------------------------------------------------------------------------------
334      //
335      // UNIT TESTS
336      //
337      //--------------------------------------------------------------------------------------------------------------------
338    
339      public static final String TESTS_KEY = "tests";
340    
341      /**
342       * Value of measure for this metric can be saved from Sensor, taking into account following rules:
343       * <ul>
344       * <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>
345       * <li>If tool has been activated, but there was no unit tests to run, then zero value should be saved for project.</li>
346       * <li>Non-zero value should be saved for resources representing tests. And Sonar provides default Decorator, which will decorate parent resources.</li>
347       * <li>Should include {@link #TEST_FAILURES} and {@link #TEST_ERRORS}, but should not include {@link #SKIPPED_TESTS}.</li>
348       * </ul>
349       */
350      public static final Metric TESTS = new Metric.Builder(TESTS_KEY, "Unit tests", Metric.ValueType.INT)
351        .setDescription("Number of unit tests")
352        .setDirection(Metric.DIRECTION_WORST)
353        .setQualitative(false)
354        .setDomain(DOMAIN_TESTS)
355        .create();
356    
357      public static final String TEST_EXECUTION_TIME_KEY = "test_execution_time";
358      public static final Metric TEST_EXECUTION_TIME = new Metric.Builder(TEST_EXECUTION_TIME_KEY, "Unit tests duration", Metric.ValueType.MILLISEC)
359        .setDescription("Execution duration of unit tests")
360        .setDirection(Metric.DIRECTION_WORST)
361        .setQualitative(false)
362        .setDomain(DOMAIN_TESTS)
363        .create();
364    
365      public static final String TEST_ERRORS_KEY = "test_errors";
366      public static final Metric TEST_ERRORS = new Metric.Builder(TEST_ERRORS_KEY, "Unit test errors", Metric.ValueType.INT)
367        .setDescription("Number of unit test errors")
368        .setDirection(Metric.DIRECTION_WORST)
369        .setQualitative(false)
370        .setDomain(DOMAIN_TESTS)
371        .setBestValue(0.0)
372        .setOptimizedBestValue(true)
373        .create();
374    
375      public static final String SKIPPED_TESTS_KEY = "skipped_tests";
376      public static final Metric SKIPPED_TESTS = new Metric.Builder(SKIPPED_TESTS_KEY, "Skipped unit tests", Metric.ValueType.INT)
377        .setDescription("Number of skipped unit tests")
378        .setDirection(Metric.DIRECTION_WORST)
379        .setQualitative(false)
380        .setDomain(DOMAIN_TESTS)
381        .setBestValue(0.0)
382        .setOptimizedBestValue(true)
383        .create();
384    
385      public static final String TEST_FAILURES_KEY = "test_failures";
386      public static final Metric TEST_FAILURES = new Metric.Builder(TEST_FAILURES_KEY, "Unit test failures", Metric.ValueType.INT)
387        .setDescription("Number of unit test failures")
388        .setDirection(Metric.DIRECTION_WORST)
389        .setQualitative(false)
390        .setDomain(DOMAIN_TESTS)
391        .setBestValue(0.0)
392        .setOptimizedBestValue(true)
393        .create();
394    
395      public static final String TEST_SUCCESS_DENSITY_KEY = "test_success_density";
396      public static final Metric TEST_SUCCESS_DENSITY = new Metric.Builder(TEST_SUCCESS_DENSITY_KEY, "Unit test success (%)", Metric.ValueType.PERCENT)
397        .setDescription("Density of successful unit tests")
398        .setDirection(Metric.DIRECTION_BETTER)
399        .setQualitative(true)
400        .setDomain(DOMAIN_TESTS)
401        .setWorstValue(0.0)
402        .setBestValue(100.0)
403        .setOptimizedBestValue(true)
404        .create();
405    
406      public static final String TEST_DATA_KEY = "test_data";
407      public static final Metric TEST_DATA = new Metric.Builder(TEST_DATA_KEY, "Unit tests details", Metric.ValueType.DATA)
408        .setDescription("Unit tests details")
409        .setDirection(Metric.DIRECTION_WORST)
410        .setDomain(DOMAIN_TESTS)
411        .create();
412    
413      public static final String COVERAGE_KEY = "coverage";
414      public static final Metric COVERAGE = new Metric.Builder(COVERAGE_KEY, "Coverage", Metric.ValueType.PERCENT)
415        .setDescription("Coverage by unit tests")
416        .setDirection(Metric.DIRECTION_BETTER)
417        .setQualitative(true)
418        .setDomain(DOMAIN_TESTS)
419        .setWorstValue(0.0)
420        .setBestValue(100.0)
421        .create();
422    
423      public static final String NEW_COVERAGE_KEY = "new_coverage";
424      public static final Metric NEW_COVERAGE = new Metric.Builder(NEW_COVERAGE_KEY, "New coverage", Metric.ValueType.PERCENT)
425        .setDescription("Coverage of new/changed code")
426        .setDirection(Metric.DIRECTION_BETTER)
427        .setQualitative(true)
428        .setDomain(DOMAIN_TESTS)
429        .setWorstValue(0.0)
430        .setBestValue(100.0)
431        .create();
432    
433      public static final String LINES_TO_COVER_KEY = "lines_to_cover";
434    
435      /**
436       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
437       */
438      public static final Metric LINES_TO_COVER = new Metric.Builder(LINES_TO_COVER_KEY, "Lines to cover", Metric.ValueType.INT)
439        .setDescription("Lines to cover")
440        .setDirection(Metric.DIRECTION_BETTER)
441        .setQualitative(false)
442        .setDomain(DOMAIN_TESTS)
443        .setFormula(new SumChildValuesFormula(false))
444        .setHidden(true)
445        .create();
446    
447      public static final String NEW_LINES_TO_COVER_KEY = "new_lines_to_cover";
448      public static final Metric NEW_LINES_TO_COVER = new Metric.Builder(NEW_LINES_TO_COVER_KEY, "New lines to cover", Metric.ValueType.INT)
449        .setDescription("New lines to cover")
450        .setDirection(Metric.DIRECTION_WORST)
451        .setQualitative(false)
452        .setDomain(DOMAIN_TESTS)
453        .setFormula(new SumChildValuesFormula(false))
454        .create();
455    
456      public static final String UNCOVERED_LINES_KEY = "uncovered_lines";
457    
458      /**
459       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
460       */
461      public static final Metric UNCOVERED_LINES = new Metric.Builder(UNCOVERED_LINES_KEY, "Uncovered lines", Metric.ValueType.INT)
462        .setDescription("Uncovered lines")
463        .setDirection(Metric.DIRECTION_WORST)
464        .setDomain(DOMAIN_TESTS)
465        .setFormula(new SumChildValuesFormula(false))
466        .setBestValue(0.0)
467        .create();
468    
469      public static final String NEW_UNCOVERED_LINES_KEY = "new_uncovered_lines";
470      public static final Metric NEW_UNCOVERED_LINES = new Metric.Builder(NEW_UNCOVERED_LINES_KEY, "New uncovered lines", Metric.ValueType.INT)
471        .setDescription("New uncovered lines")
472        .setDirection(Metric.DIRECTION_WORST)
473        .setDomain(DOMAIN_TESTS)
474        .setFormula(new SumChildValuesFormula(false))
475        .setBestValue(0.0)
476        .create();
477    
478      public static final String LINE_COVERAGE_KEY = "line_coverage";
479      public static final Metric LINE_COVERAGE = new Metric.Builder(LINE_COVERAGE_KEY, "Line coverage", Metric.ValueType.PERCENT)
480        .setDescription("Line coverage")
481        .setDirection(Metric.DIRECTION_BETTER)
482        .setQualitative(true)
483        .setDomain(DOMAIN_TESTS)
484        .setWorstValue(0.0)
485        .setBestValue(100.0)
486        .create();
487    
488      public static final String NEW_LINE_COVERAGE_KEY = "new_line_coverage";
489      public static final Metric NEW_LINE_COVERAGE = new Metric.Builder(NEW_LINE_COVERAGE_KEY, "New line coverage", Metric.ValueType.PERCENT)
490        .setDescription("Line coverage of added/changed code")
491        .setDirection(Metric.DIRECTION_BETTER)
492        .setQualitative(true)
493        .setWorstValue(0.0)
494        .setBestValue(100.0)
495        .setDomain(DOMAIN_TESTS)
496        .create();
497    
498      public static final String COVERAGE_LINE_HITS_DATA_KEY = "coverage_line_hits_data";
499    
500      /**
501       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
502       */
503      public static final Metric COVERAGE_LINE_HITS_DATA = new Metric.Builder(COVERAGE_LINE_HITS_DATA_KEY, "Coverage hits by line", Metric.ValueType.DATA)
504        .setDomain(DOMAIN_TESTS)
505        .create();
506    
507      public static final String CONDITIONS_TO_COVER_KEY = "conditions_to_cover";
508    
509      /**
510       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
511       */
512      public static final Metric CONDITIONS_TO_COVER = new Metric.Builder(CONDITIONS_TO_COVER_KEY, "Conditions to cover", Metric.ValueType.INT)
513        .setDescription("Conditions to cover")
514        .setDomain(DOMAIN_TESTS)
515        .setFormula(new SumChildValuesFormula(false))
516        .setHidden(true)
517        .create();
518    
519      public static final String NEW_CONDITIONS_TO_COVER_KEY = "new_conditions_to_cover";
520      public static final Metric NEW_CONDITIONS_TO_COVER = new Metric.Builder(NEW_CONDITIONS_TO_COVER_KEY, "New conditions to cover", Metric.ValueType.INT)
521        .setDescription("New conditions to cover")
522        .setDomain(DOMAIN_TESTS)
523        .setFormula(new SumChildValuesFormula(false))
524        .create();
525    
526      public static final String UNCOVERED_CONDITIONS_KEY = "uncovered_conditions";
527    
528      /**
529       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
530       */
531      public static final Metric UNCOVERED_CONDITIONS = new Metric.Builder(UNCOVERED_CONDITIONS_KEY, "Uncovered conditions", Metric.ValueType.INT)
532        .setDescription("Uncovered conditions")
533        .setDirection(Metric.DIRECTION_WORST)
534        .setDomain(DOMAIN_TESTS)
535        .setFormula(new SumChildValuesFormula(false))
536        .setBestValue(0.0)
537        .create();
538    
539      public static final String NEW_UNCOVERED_CONDITIONS_KEY = "new_uncovered_conditions";
540      public static final Metric NEW_UNCOVERED_CONDITIONS = new Metric.Builder(NEW_UNCOVERED_CONDITIONS_KEY, "New uncovered conditions", Metric.ValueType.INT)
541        .setDescription("New uncovered conditions")
542        .setDirection(Metric.DIRECTION_WORST)
543        .setDomain(DOMAIN_TESTS)
544        .setFormula(new SumChildValuesFormula(false))
545        .setBestValue(0.0)
546        .create();
547    
548      public static final String BRANCH_COVERAGE_KEY = "branch_coverage";
549      public static final Metric BRANCH_COVERAGE = new Metric.Builder(BRANCH_COVERAGE_KEY, "Branch coverage", Metric.ValueType.PERCENT)
550        .setDescription("Branch coverage")
551        .setDirection(Metric.DIRECTION_BETTER)
552        .setQualitative(true)
553        .setDomain(DOMAIN_TESTS)
554        .setWorstValue(0.0)
555        .setBestValue(100.0)
556        .create();
557    
558      public static final String NEW_BRANCH_COVERAGE_KEY = "new_branch_coverage";
559      public static final Metric NEW_BRANCH_COVERAGE = new Metric.Builder(NEW_BRANCH_COVERAGE_KEY, "New branch coverage", Metric.ValueType.PERCENT)
560        .setDescription("Branch coverage of new/changed code")
561        .setDirection(Metric.DIRECTION_BETTER)
562        .setQualitative(true)
563        .setDomain(DOMAIN_TESTS)
564        .setWorstValue(0.0)
565        .setBestValue(100.0)
566        .create();
567    
568      /**
569       * @deprecated in 2.7. Replaced by {@link #CONDITIONS_BY_LINE_KEY} and {@link #COVERED_CONDITIONS_BY_LINE_KEY}
570       */
571      @Deprecated
572      public static final String BRANCH_COVERAGE_HITS_DATA_KEY = "branch_coverage_hits_data";
573    
574      /**
575       * @deprecated in 2.7. Replaced by metrics {@link #CONDITIONS_BY_LINE} and {@link #COVERED_CONDITIONS_BY_LINE}
576       */
577      @Deprecated
578      public static final Metric BRANCH_COVERAGE_HITS_DATA = new Metric.Builder(BRANCH_COVERAGE_HITS_DATA_KEY, "Branch coverage hits", Metric.ValueType.DATA)
579        .setDomain(DOMAIN_TESTS)
580        .create();
581    
582      public static final String CONDITIONS_BY_LINE_KEY = "conditions_by_line";
583    
584      /**
585       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
586       *
587       * @since 2.7
588       */
589      public static final Metric CONDITIONS_BY_LINE = new Metric.Builder(CONDITIONS_BY_LINE_KEY, "Conditions by line", Metric.ValueType.DATA)
590        .setDomain(DOMAIN_TESTS)
591        .create();
592    
593      public static final String COVERED_CONDITIONS_BY_LINE_KEY = "covered_conditions_by_line";
594    
595      /**
596       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
597       *
598       * @since 2.7
599       */
600      public static final Metric COVERED_CONDITIONS_BY_LINE = new Metric.Builder(COVERED_CONDITIONS_BY_LINE_KEY, "Covered conditions by line", Metric.ValueType.DATA)
601        .setDomain(DOMAIN_TESTS)
602        .create();
603    
604    
605      //--------------------------------------------------------------------------------------------------------------------
606      //
607      // INTEGRATION TESTS
608      //
609      //--------------------------------------------------------------------------------------------------------------------
610    
611      /**
612       * @since 2.12
613       */
614      public static final String IT_COVERAGE_KEY = "it_coverage";
615    
616      /**
617       * @since 2.12
618       */
619      public static final Metric IT_COVERAGE = new Metric.Builder(IT_COVERAGE_KEY, "IT Coverage", Metric.ValueType.PERCENT)
620        .setDescription("Coverage by integration tests")
621        .setDirection(Metric.DIRECTION_BETTER)
622        .setQualitative(true)
623        .setDomain(DOMAIN_INTEGRATION_TESTS)
624        .setWorstValue(0.0)
625        .setBestValue(100.0)
626        .create();
627    
628      /**
629       * @since 2.12
630       */
631      public static final String NEW_IT_COVERAGE_KEY = "new_it_coverage";
632    
633      /**
634       * @since 2.12
635       */
636      public static final Metric NEW_IT_COVERAGE = new Metric.Builder(NEW_IT_COVERAGE_KEY, "New Coverage by IT", Metric.ValueType.PERCENT)
637        .setDescription("Integration Tests Coverage of new/changed code")
638        .setDirection(Metric.DIRECTION_BETTER)
639        .setQualitative(true)
640        .setDomain(DOMAIN_INTEGRATION_TESTS)
641        .setWorstValue(0.0)
642        .setBestValue(100.0)
643        .create();
644    
645      /**
646       * @since 2.12
647       */
648      public static final String IT_LINES_TO_COVER_KEY = "it_lines_to_cover";
649    
650      /**
651       * @since 2.12
652       */
653      public static final Metric IT_LINES_TO_COVER = new Metric.Builder(IT_LINES_TO_COVER_KEY, "IT Lines to Cover", Metric.ValueType.INT)
654        .setDescription("Lines to cover by Integration Tests")
655        .setDirection(Metric.DIRECTION_BETTER)
656        .setDomain(DOMAIN_INTEGRATION_TESTS)
657        .setQualitative(false)
658        .setFormula(new SumChildValuesFormula(false))
659        .setHidden(true)
660        .create();
661    
662      /**
663       * @since 2.12
664       */
665      public static final String NEW_IT_LINES_TO_COVER_KEY = "new_it_lines_to_cover";
666    
667      /**
668       * @since 2.12
669       */
670      public static final Metric NEW_IT_LINES_TO_COVER = new Metric.Builder(NEW_IT_LINES_TO_COVER_KEY, "New Lines to Cover by IT", Metric.ValueType.INT)
671        .setDescription("New lines to cover by Integration Tests")
672        .setDirection(Metric.DIRECTION_WORST)
673        .setQualitative(false)
674        .setDomain(DOMAIN_INTEGRATION_TESTS)
675        .setFormula(new SumChildValuesFormula(false))
676        .create();
677    
678      /**
679       * @since 2.12
680       */
681      public static final String IT_UNCOVERED_LINES_KEY = "it_uncovered_lines";
682    
683      /**
684       * @since 2.12
685       */
686      public static final Metric IT_UNCOVERED_LINES = new Metric.Builder(IT_UNCOVERED_LINES_KEY, "IT Uncovered Lines", Metric.ValueType.INT)
687        .setDescription("IT uncovered lines")
688        .setDirection(Metric.DIRECTION_WORST)
689        .setQualitative(false)
690        .setDomain(DOMAIN_INTEGRATION_TESTS)
691        .setFormula(new SumChildValuesFormula(false))
692        .create();
693    
694      /**
695       * @since 2.12
696       */
697      public static final String NEW_IT_UNCOVERED_LINES_KEY = "new_it_uncovered_lines";
698    
699      /**
700       * @since 2.12
701       */
702      public static final Metric NEW_IT_UNCOVERED_LINES = new Metric.Builder(NEW_IT_UNCOVERED_LINES_KEY, "New Uncovered Lines by IT", Metric.ValueType.INT)
703        .setDescription("New uncovered lines by Integration Tests")
704        .setDirection(Metric.DIRECTION_WORST)
705        .setDomain(DOMAIN_INTEGRATION_TESTS)
706        .setFormula(new SumChildValuesFormula(false))
707        .setBestValue(0.0)
708        .create();
709    
710      /**
711       * @since 2.12
712       */
713      public static final String IT_LINE_COVERAGE_KEY = "it_line_coverage";
714    
715      /**
716       * @since 2.12
717       */
718      public static final Metric IT_LINE_COVERAGE = new Metric.Builder(IT_LINE_COVERAGE_KEY, "IT Line coverage", Metric.ValueType.PERCENT)
719        .setDescription("IT line coverage")
720        .setDirection(Metric.DIRECTION_BETTER)
721        .setQualitative(true)
722        .setDomain(DOMAIN_INTEGRATION_TESTS)
723        .create();
724    
725      /**
726       * @since 2.12
727       */
728      public static final String NEW_IT_LINE_COVERAGE_KEY = "new_it_line_coverage";
729    
730      /**
731       * @since 2.12
732       */
733      public static final Metric NEW_IT_LINE_COVERAGE = new Metric.Builder(NEW_IT_LINE_COVERAGE_KEY, "New Line Coverage by IT", Metric.ValueType.PERCENT)
734        .setDescription("Line Coverage by Integration Tests of added/changed code")
735        .setDirection(Metric.DIRECTION_BETTER)
736        .setQualitative(true)
737        .setWorstValue(0.0)
738        .setBestValue(100.0)
739        .setDomain(DOMAIN_INTEGRATION_TESTS)
740        .create();
741    
742      /**
743       * @since 2.12
744       */
745      public static final String IT_COVERAGE_LINE_HITS_DATA_KEY = "it_coverage_line_hits_data";
746    
747      /**
748       * @since 2.12
749       */
750      public static final Metric IT_COVERAGE_LINE_HITS_DATA = new Metric.Builder(IT_COVERAGE_LINE_HITS_DATA_KEY, "IT Coverage Hits Data", Metric.ValueType.DATA)
751        .setDescription("IT Code coverage line hits data")
752        .setDirection(Metric.DIRECTION_NONE)
753        .setQualitative(false)
754        .setDomain(DOMAIN_INTEGRATION_TESTS)
755        .create();
756    
757      /**
758       * @since 2.12
759       */
760      public static final String IT_CONDITIONS_TO_COVER_KEY = "it_conditions_to_cover";
761    
762      /**
763       * @since 2.12
764       */
765      public static final Metric IT_CONDITIONS_TO_COVER = new Metric.Builder(IT_CONDITIONS_TO_COVER_KEY, "IT Branches to Cover", Metric.ValueType.INT)
766        .setDescription("IT Conditions to cover")
767        .setDirection(Metric.DIRECTION_BETTER)
768        .setQualitative(false)
769        .setDomain(DOMAIN_INTEGRATION_TESTS)
770        .setFormula(new SumChildValuesFormula(false))
771        .setHidden(true)
772        .create();
773    
774      /**
775       * @since 2.12
776       */
777      public static final String NEW_IT_CONDITIONS_TO_COVER_KEY = "new_it_conditions_to_cover";
778    
779      /**
780       * @since 2.12
781       */
782      public static final Metric NEW_IT_CONDITIONS_TO_COVER = new Metric.Builder(NEW_IT_CONDITIONS_TO_COVER_KEY, "New Conditions to Cover by IT", Metric.ValueType.INT)
783        .setDescription("New conditions to cover by Integration Tests")
784        .setDomain(DOMAIN_INTEGRATION_TESTS)
785        .setFormula(new SumChildValuesFormula(false))
786        .create();
787    
788      /**
789       * @since 2.12
790       */
791      public static final String IT_UNCOVERED_CONDITIONS_KEY = "it_uncovered_conditions";
792    
793      /**
794       * @since 2.12
795       */
796      public static final Metric IT_UNCOVERED_CONDITIONS = new Metric.Builder(IT_UNCOVERED_CONDITIONS_KEY, "IT Uncovered Branches", Metric.ValueType.INT)
797        .setDescription("IT Uncovered conditions")
798        .setDirection(Metric.DIRECTION_WORST)
799        .setDomain(DOMAIN_INTEGRATION_TESTS)
800        .setFormula(new SumChildValuesFormula(false))
801        .create();
802    
803      /**
804       * @since 2.12
805       */
806      public static final String NEW_IT_UNCOVERED_CONDITIONS_KEY = "new_it_uncovered_conditions";
807    
808      /**
809       * @since 2.12
810       */
811      public static final Metric NEW_IT_UNCOVERED_CONDITIONS = new Metric.Builder(NEW_IT_UNCOVERED_CONDITIONS_KEY, "New Uncovered Conditions by IT", Metric.ValueType.INT)
812        .setDescription("New uncovered conditions by Integration Tests")
813        .setDirection(Metric.DIRECTION_WORST)
814        .setDomain(DOMAIN_INTEGRATION_TESTS)
815        .setFormula(new SumChildValuesFormula(false))
816        .setBestValue(0.0)
817        .create();
818    
819      /**
820       * @since 2.12
821       */
822      public static final String IT_BRANCH_COVERAGE_KEY = "it_branch_coverage";
823    
824      /**
825       * @since 2.12
826       */
827      public static final Metric IT_BRANCH_COVERAGE = new Metric.Builder(IT_BRANCH_COVERAGE_KEY, "IT Branch Coverage", Metric.ValueType.PERCENT)
828        .setDescription("IT Branch coverage")
829        .setDirection(Metric.DIRECTION_BETTER)
830        .setQualitative(true)
831        .setDomain(DOMAIN_INTEGRATION_TESTS)
832        .setWorstValue(0.0)
833        .setBestValue(100.0)
834        .create();
835    
836      /**
837       * @since 2.12
838       */
839      public static final String NEW_IT_BRANCH_COVERAGE_KEY = "new_it_branch_coverage";
840    
841      /**
842       * @since 2.12
843       */
844      public static final Metric NEW_IT_BRANCH_COVERAGE = new Metric.Builder(NEW_IT_BRANCH_COVERAGE_KEY, "New Branch Coverage by IT", Metric.ValueType.PERCENT)
845        .setDescription("Branch coverage by Integration Tests of new/changed code")
846        .setDirection(Metric.DIRECTION_BETTER)
847        .setQualitative(true)
848        .setDomain(DOMAIN_INTEGRATION_TESTS)
849        .setWorstValue(0.0)
850        .setBestValue(100.0)
851        .create();
852    
853      /**
854       * @since 2.12
855       */
856      public static final String IT_CONDITIONS_BY_LINE_KEY = "it_conditions_by_line";
857    
858      /**
859       * @since 2.12
860       */
861      public static final Metric IT_CONDITIONS_BY_LINE = new Metric.Builder(IT_CONDITIONS_BY_LINE_KEY, "IT Branches by Line", Metric.ValueType.DATA)
862        .setDomain(DOMAIN_INTEGRATION_TESTS)
863        .create();
864    
865      /**
866       * @since 2.12
867       */
868      public static final String IT_COVERED_CONDITIONS_BY_LINE_KEY = "it_covered_conditions_by_line";
869    
870      /**
871       * @since 2.12
872       */
873      public static final Metric IT_COVERED_CONDITIONS_BY_LINE = new Metric.Builder(IT_COVERED_CONDITIONS_BY_LINE_KEY, "IT Covered Branches by Line", Metric.ValueType.DATA)
874        .setDomain(DOMAIN_INTEGRATION_TESTS)
875        .create();
876    
877    
878      //--------------------------------------------------------------------------------------------------------------------
879      //
880      // DUPLICATIONS
881      //
882      //--------------------------------------------------------------------------------------------------------------------
883    
884      public static final String DUPLICATED_LINES_KEY = "duplicated_lines";
885      public static final Metric DUPLICATED_LINES = new Metric.Builder(DUPLICATED_LINES_KEY, "Duplicated lines", Metric.ValueType.INT)
886        .setDescription("Duplicated lines")
887        .setDirection(Metric.DIRECTION_WORST)
888        .setDomain(DOMAIN_DUPLICATION)
889        .setBestValue(0.0)
890        .setOptimizedBestValue(true)
891        .create();
892    
893      public static final String DUPLICATED_BLOCKS_KEY = "duplicated_blocks";
894      public static final Metric DUPLICATED_BLOCKS = new Metric.Builder(DUPLICATED_BLOCKS_KEY, "Duplicated blocks", Metric.ValueType.INT)
895        .setDescription("Duplicated blocks")
896        .setDirection(Metric.DIRECTION_WORST)
897        .setDomain(DOMAIN_DUPLICATION)
898        .setBestValue(0.0)
899        .setOptimizedBestValue(true)
900        .create();
901    
902      public static final String DUPLICATED_FILES_KEY = "duplicated_files";
903      public static final Metric DUPLICATED_FILES = new Metric.Builder(DUPLICATED_FILES_KEY, "Duplicated files", Metric.ValueType.INT)
904        .setDescription("Duplicated files")
905        .setDirection(Metric.DIRECTION_WORST)
906        .setQualitative(true)
907        .setDomain(DOMAIN_DUPLICATION)
908        .setBestValue(0.0)
909        .setOptimizedBestValue(true)
910        .create();
911    
912      public static final String DUPLICATED_LINES_DENSITY_KEY = "duplicated_lines_density";
913      public static final Metric DUPLICATED_LINES_DENSITY = new Metric.Builder(DUPLICATED_LINES_DENSITY_KEY, "Duplicated lines (%)", Metric.ValueType.PERCENT)
914        .setDescription("Duplicated lines balanced by statements")
915        .setDirection(Metric.DIRECTION_WORST)
916        .setQualitative(true)
917        .setDomain(DOMAIN_DUPLICATION)
918        .setWorstValue(50.0)
919        .setBestValue(0.0)
920        .setOptimizedBestValue(true)
921        .create();
922    
923      public static final String DUPLICATIONS_DATA_KEY = "duplications_data";
924      public static final Metric DUPLICATIONS_DATA = new Metric.Builder(DUPLICATIONS_DATA_KEY, "Duplications details", Metric.ValueType.DATA)
925        .setDescription("Duplications details")
926        .setDirection(Metric.DIRECTION_NONE)
927        .setQualitative(false)
928        .setDomain(DOMAIN_DUPLICATION)
929        .create();
930    
931    
932      //--------------------------------------------------------------------------------------------------------------------
933      //
934      // CODING RULES
935      //
936      //--------------------------------------------------------------------------------------------------------------------
937      /**
938       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
939       */
940      @Deprecated
941      public static final String USABILITY_KEY = "usability";
942    
943      /**
944       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
945       */
946      @Deprecated
947      public static final Metric USABILITY = new Metric(USABILITY_KEY, "Usability", "Usability", Metric.ValueType.PERCENT,
948        Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
949    
950      /**
951       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
952       */
953      @Deprecated
954      public static final String RELIABILITY_KEY = "reliability";
955    
956      /**
957       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
958       */
959      @Deprecated
960      public static final Metric RELIABILITY = new Metric(RELIABILITY_KEY, "Reliability", "Reliability", Metric.ValueType.PERCENT,
961        Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
962    
963      /**
964       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
965       */
966      @Deprecated
967      public static final String EFFICIENCY_KEY = "efficiency";
968    
969      /**
970       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
971       */
972      @Deprecated
973      public static final Metric EFFICIENCY = new Metric(EFFICIENCY_KEY, "Efficiency", "Efficiency", Metric.ValueType.PERCENT,
974        Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
975    
976      /**
977       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
978       */
979      @Deprecated
980      public static final String PORTABILITY_KEY = "portability";
981    
982      /**
983       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
984       */
985      @Deprecated
986      public static final Metric PORTABILITY = new Metric(PORTABILITY_KEY, "Portability", "Portability", Metric.ValueType.PERCENT,
987        Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
988    
989      /**
990       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
991       */
992      @Deprecated
993      public static final String MAINTAINABILITY_KEY = "maintainability";
994    
995      /**
996       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
997       */
998      @Deprecated
999      public static final Metric MAINTAINABILITY = new Metric.Builder(MAINTAINABILITY_KEY, "Maintainability", Metric.ValueType.PERCENT)
1000        .setDescription("Maintainability")
1001        .setDirection(Metric.DIRECTION_BETTER)
1002        .setQualitative(true)
1003        .setDomain(DOMAIN_RULE_CATEGORIES)
1004        .setBestValue(100.0)
1005        .setOptimizedBestValue(true)
1006        .create();
1007    
1008      public static final String WEIGHTED_VIOLATIONS_KEY = "weighted_violations";
1009      public static final Metric WEIGHTED_VIOLATIONS = new Metric.Builder(WEIGHTED_VIOLATIONS_KEY, "Weighted violations", Metric.ValueType.INT)
1010        .setDescription("Weighted Violations")
1011        .setDirection(Metric.DIRECTION_WORST)
1012        .setQualitative(true)
1013        .setDomain(DOMAIN_RULES)
1014        .create();
1015    
1016      public static final String VIOLATIONS_DENSITY_KEY = "violations_density";
1017      public static final Metric VIOLATIONS_DENSITY = new Metric.Builder(VIOLATIONS_DENSITY_KEY, "Rules compliance", Metric.ValueType.PERCENT)
1018        .setDescription("Rules compliance")
1019        .setDirection(Metric.DIRECTION_BETTER)
1020        .setQualitative(true)
1021        .setDomain(DOMAIN_RULES)
1022        .create();
1023    
1024      public static final String VIOLATIONS_KEY = "violations";
1025      public static final Metric VIOLATIONS = new Metric.Builder(VIOLATIONS_KEY, "Violations", Metric.ValueType.INT)
1026        .setDescription("Violations")
1027        .setDirection(Metric.DIRECTION_WORST)
1028        .setQualitative(false)
1029        .setDomain(DOMAIN_RULES)
1030        .setBestValue(0.0)
1031        .setOptimizedBestValue(true)
1032        .create();
1033    
1034      public static final String BLOCKER_VIOLATIONS_KEY = "blocker_violations";
1035      public static final Metric BLOCKER_VIOLATIONS = new Metric.Builder(BLOCKER_VIOLATIONS_KEY, "Blocker violations", Metric.ValueType.INT)
1036        .setDescription("Blocker violations")
1037        .setDirection(Metric.DIRECTION_WORST)
1038        .setQualitative(false)
1039        .setDomain(DOMAIN_RULES)
1040        .setBestValue(0.0)
1041        .setOptimizedBestValue(true)
1042        .create();
1043    
1044      public static final String CRITICAL_VIOLATIONS_KEY = "critical_violations";
1045      public static final Metric CRITICAL_VIOLATIONS = new Metric.Builder(CRITICAL_VIOLATIONS_KEY, "Critical violations", Metric.ValueType.INT)
1046        .setDescription("Critical violations")
1047        .setDirection(Metric.DIRECTION_WORST)
1048        .setQualitative(false)
1049        .setDomain(DOMAIN_RULES)
1050        .setBestValue(0.0)
1051        .setOptimizedBestValue(true)
1052        .create();
1053    
1054      public static final String MAJOR_VIOLATIONS_KEY = "major_violations";
1055      public static final Metric MAJOR_VIOLATIONS = new Metric.Builder(MAJOR_VIOLATIONS_KEY, "Major violations", Metric.ValueType.INT)
1056        .setDescription("Major violations")
1057        .setDirection(Metric.DIRECTION_WORST)
1058        .setQualitative(false)
1059        .setDomain(DOMAIN_RULES)
1060        .setBestValue(0.0)
1061        .setOptimizedBestValue(true)
1062        .create();
1063    
1064      public static final String MINOR_VIOLATIONS_KEY = "minor_violations";
1065      public static final Metric MINOR_VIOLATIONS = new Metric.Builder(MINOR_VIOLATIONS_KEY, "Minor violations", Metric.ValueType.INT)
1066        .setDescription("Minor violations")
1067        .setDirection(Metric.DIRECTION_WORST)
1068        .setQualitative(false)
1069        .setDomain(DOMAIN_RULES)
1070        .setBestValue(0.0)
1071        .setOptimizedBestValue(true)
1072        .create();
1073    
1074      public static final String INFO_VIOLATIONS_KEY = "info_violations";
1075      public static final Metric INFO_VIOLATIONS = new Metric.Builder(INFO_VIOLATIONS_KEY, "Info violations", Metric.ValueType.INT)
1076        .setDescription("Info violations")
1077        .setDirection(Metric.DIRECTION_WORST)
1078        .setQualitative(false)
1079        .setDomain(DOMAIN_RULES)
1080        .setBestValue(0.0)
1081        .setOptimizedBestValue(true)
1082        .create();
1083    
1084      public static final String NEW_VIOLATIONS_KEY = "new_violations";
1085      public static final Metric NEW_VIOLATIONS = new Metric.Builder(NEW_VIOLATIONS_KEY, "New Violations", Metric.ValueType.INT)
1086        .setDescription("New Violations")
1087        .setDirection(Metric.DIRECTION_WORST)
1088        .setQualitative(false)
1089        .setDomain(DOMAIN_RULES)
1090        .setBestValue(0.0)
1091        .setOptimizedBestValue(true)
1092        .create();
1093    
1094      public static final String NEW_BLOCKER_VIOLATIONS_KEY = "new_blocker_violations";
1095      public static final Metric NEW_BLOCKER_VIOLATIONS = new Metric.Builder(NEW_BLOCKER_VIOLATIONS_KEY, "New Blocker violations", Metric.ValueType.INT)
1096        .setDescription("New Blocker violations")
1097        .setDirection(Metric.DIRECTION_WORST)
1098        .setQualitative(false)
1099        .setDomain(DOMAIN_RULES)
1100        .setBestValue(0.0)
1101        .setOptimizedBestValue(true)
1102        .create();
1103    
1104      public static final String NEW_CRITICAL_VIOLATIONS_KEY = "new_critical_violations";
1105      public static final Metric NEW_CRITICAL_VIOLATIONS = new Metric.Builder(NEW_CRITICAL_VIOLATIONS_KEY, "New Critical violations", Metric.ValueType.INT)
1106        .setDescription("New Critical violations")
1107        .setDirection(Metric.DIRECTION_WORST)
1108        .setQualitative(false)
1109        .setDomain(DOMAIN_RULES)
1110        .setBestValue(0.0)
1111        .setOptimizedBestValue(true)
1112        .create();
1113    
1114      public static final String NEW_MAJOR_VIOLATIONS_KEY = "new_major_violations";
1115      public static final Metric NEW_MAJOR_VIOLATIONS = new Metric.Builder(NEW_MAJOR_VIOLATIONS_KEY, "New Major violations", Metric.ValueType.INT)
1116        .setDescription("New Major violations")
1117        .setDirection(Metric.DIRECTION_WORST)
1118        .setQualitative(false)
1119        .setDomain(DOMAIN_RULES)
1120        .setBestValue(0.0)
1121        .setOptimizedBestValue(true)
1122        .create();
1123    
1124      public static final String NEW_MINOR_VIOLATIONS_KEY = "new_minor_violations";
1125      public static final Metric NEW_MINOR_VIOLATIONS = new Metric.Builder(NEW_MINOR_VIOLATIONS_KEY, "New Minor violations", Metric.ValueType.INT)
1126        .setDescription("New Minor violations")
1127        .setDirection(Metric.DIRECTION_WORST)
1128        .setQualitative(false)
1129        .setDomain(DOMAIN_RULES)
1130        .setBestValue(0.0)
1131        .setOptimizedBestValue(true)
1132        .create();
1133    
1134      public static final String NEW_INFO_VIOLATIONS_KEY = "new_info_violations";
1135      public static final Metric NEW_INFO_VIOLATIONS = new Metric.Builder(NEW_INFO_VIOLATIONS_KEY, "New Info violations", Metric.ValueType.INT)
1136        .setDescription("New Info violations")
1137        .setDirection(Metric.DIRECTION_WORST)
1138        .setQualitative(false)
1139        .setDomain(DOMAIN_RULES)
1140        .setBestValue(0.0)
1141        .setOptimizedBestValue(true)
1142        .create();
1143    
1144    
1145      //--------------------------------------------------------------------------------------------------------------------
1146      //
1147      // DESIGN
1148      //
1149      //--------------------------------------------------------------------------------------------------------------------
1150    
1151      public static final String ABSTRACTNESS_KEY = "abstractness";
1152      public static final Metric ABSTRACTNESS = new Metric.Builder(ABSTRACTNESS_KEY, "Abstractness", Metric.ValueType.PERCENT)
1153        .setDescription("Abstractness")
1154        .setDirection(Metric.DIRECTION_NONE)
1155        .setQualitative(false)
1156        .setDomain(DOMAIN_DESIGN)
1157        .create();
1158    
1159      public static final String INSTABILITY_KEY = "instability";
1160      public static final Metric INSTABILITY = new Metric.Builder(INSTABILITY_KEY, "Instability", Metric.ValueType.PERCENT)
1161        .setDescription("Instability")
1162        .setDirection(Metric.DIRECTION_NONE)
1163        .setQualitative(false)
1164        .setDomain(DOMAIN_DESIGN)
1165        .create();
1166    
1167      public static final String DISTANCE_KEY = "distance";
1168      public static final Metric DISTANCE = new Metric.Builder(DISTANCE_KEY, "Distance", Metric.ValueType.FLOAT)
1169        .setDescription("Distance")
1170        .setDirection(Metric.DIRECTION_NONE)
1171        .setQualitative(false)
1172        .setDomain(DOMAIN_DESIGN)
1173        .create();
1174    
1175      public static final String DEPTH_IN_TREE_KEY = "dit";
1176      public static final Metric DEPTH_IN_TREE = new Metric.Builder(DEPTH_IN_TREE_KEY, "Depth in Tree", Metric.ValueType.INT)
1177        .setDescription("Depth in Inheritance Tree")
1178        .setDirection(Metric.DIRECTION_NONE)
1179        .setQualitative(false)
1180        .setDomain(DOMAIN_DESIGN)
1181        .create();
1182    
1183      public static final String NUMBER_OF_CHILDREN_KEY = "noc";
1184      public static final Metric NUMBER_OF_CHILDREN = new Metric.Builder(NUMBER_OF_CHILDREN_KEY, "Number of Children", Metric.ValueType.INT)
1185        .setDescription("Number of Children")
1186        .setDirection(Metric.DIRECTION_NONE)
1187        .setQualitative(false)
1188        .setDomain(DOMAIN_DESIGN)
1189        .create();
1190    
1191      public static final String RFC_KEY = "rfc";
1192      public static final Metric RFC = new Metric.Builder(RFC_KEY, "RFC", Metric.ValueType.INT)
1193        .setDescription("Response for Class")
1194        .setDirection(Metric.DIRECTION_WORST)
1195        .setQualitative(false)
1196        .setDomain(DOMAIN_DESIGN)
1197        .setFormula(new WeightedMeanAggregationFormula(CoreMetrics.FILES, false))
1198        .create();
1199    
1200      public static final String RFC_DISTRIBUTION_KEY = "rfc_distribution";
1201      public static final Metric RFC_DISTRIBUTION = new Metric.Builder(RFC_DISTRIBUTION_KEY, "Class distribution /RFC", Metric.ValueType.DISTRIB)
1202        .setDescription("Class distribution /RFC")
1203        .setDirection(Metric.DIRECTION_NONE)
1204        .setQualitative(true)
1205        .setDomain(DOMAIN_DESIGN)
1206        .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
1207        .create();
1208    
1209      public static final String LCOM4_KEY = "lcom4";
1210      public static final Metric LCOM4 = new Metric.Builder(LCOM4_KEY, "LCOM4", Metric.ValueType.FLOAT)
1211        .setDescription("Lack of Cohesion of Methods")
1212        .setDirection(Metric.DIRECTION_WORST)
1213        .setQualitative(true)
1214        .setDomain(DOMAIN_DESIGN)
1215        .setBestValue(1.0)
1216        .setFormula(new WeightedMeanAggregationFormula(CoreMetrics.FILES, false))
1217        .create();
1218    
1219      public static final String LCOM4_BLOCKS_KEY = "lcom4_blocks";
1220      public static final Metric LCOM4_BLOCKS = new Metric.Builder(LCOM4_BLOCKS_KEY, "LCOM4 blocks", Metric.ValueType.DATA)
1221        .setDescription("LCOM4 blocks")
1222        .setDirection(Metric.DIRECTION_NONE)
1223        .setQualitative(false)
1224        .setDomain(DOMAIN_DESIGN)
1225        .setHidden(true)
1226        .create();
1227    
1228      public static final String LCOM4_DISTRIBUTION_KEY = "lcom4_distribution";
1229      public static final Metric LCOM4_DISTRIBUTION = new Metric.Builder(LCOM4_DISTRIBUTION_KEY, "Class distribution /LCOM4", Metric.ValueType.DISTRIB)
1230        .setDescription("Class distribution /LCOM4")
1231        .setDirection(Metric.DIRECTION_NONE)
1232        .setQualitative(true)
1233        .setDomain(DOMAIN_DESIGN)
1234        .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
1235        .create();
1236    
1237      public static final String SUSPECT_LCOM4_DENSITY_KEY = "suspect_lcom4_density";
1238      public static final Metric SUSPECT_LCOM4_DENSITY = new Metric.Builder(SUSPECT_LCOM4_DENSITY_KEY, "Suspect LCOM4 density", Metric.ValueType.PERCENT)
1239        .setDescription("Density of classes having LCOM4>1")
1240        .setDirection(Metric.DIRECTION_WORST)
1241        .setQualitative(true)
1242        .setDomain(DOMAIN_DESIGN)
1243        .create();
1244    
1245      public static final String AFFERENT_COUPLINGS_KEY = "ca";
1246      public static final Metric AFFERENT_COUPLINGS = new Metric.Builder(AFFERENT_COUPLINGS_KEY, "Afferent couplings", Metric.ValueType.INT)
1247        .setDescription("Afferent couplings")
1248        .setDirection(Metric.DIRECTION_WORST)
1249        .setQualitative(false)
1250        .setDomain(DOMAIN_DESIGN)
1251        .create();
1252    
1253      public static final String EFFERENT_COUPLINGS_KEY = "ce";
1254      public static final Metric EFFERENT_COUPLINGS = new Metric.Builder(EFFERENT_COUPLINGS_KEY, "Efferent couplings", Metric.ValueType.INT)
1255        .setDescription("Efferent couplings")
1256        .setDirection(Metric.DIRECTION_WORST)
1257        .setQualitative(false)
1258        .setDomain(DOMAIN_DESIGN)
1259        .create();
1260    
1261      public static final String DEPENDENCY_MATRIX_KEY = "dsm";
1262      public static final Metric DEPENDENCY_MATRIX = new Metric.Builder(DEPENDENCY_MATRIX_KEY, "Dependency Matrix", Metric.ValueType.DATA)
1263        .setDescription("Dependency Matrix")
1264        .setDirection(Metric.DIRECTION_NONE)
1265        .setQualitative(false)
1266        .setDomain(DOMAIN_DESIGN)
1267        .create();
1268    
1269      public static final String PACKAGE_CYCLES_KEY = "package_cycles";
1270      public static final Metric PACKAGE_CYCLES = new Metric.Builder(PACKAGE_CYCLES_KEY, "Package cycles", Metric.ValueType.INT)
1271        .setDescription("Package cycles")
1272        .setDirection(Metric.DIRECTION_WORST)
1273        .setQualitative(true)
1274        .setDomain(DOMAIN_DESIGN)
1275        .setFormula(new SumChildValuesFormula(false))
1276        .create();
1277    
1278      public static final String PACKAGE_TANGLE_INDEX_KEY = "package_tangle_index";
1279      public static final Metric PACKAGE_TANGLE_INDEX = new Metric.Builder(PACKAGE_TANGLE_INDEX_KEY, "Package tangle index", Metric.ValueType.PERCENT)
1280        .setDescription("Package tangle index")
1281        .setDirection(Metric.DIRECTION_WORST)
1282        .setQualitative(true)
1283        .setDomain(DOMAIN_DESIGN)
1284        .create();
1285    
1286      public static final String PACKAGE_TANGLES_KEY = "package_tangles";
1287      public static final Metric PACKAGE_TANGLES = new Metric.Builder(PACKAGE_TANGLES_KEY, "File dependencies to cut", Metric.ValueType.INT)
1288        .setDescription("File dependencies to cut")
1289        .setDirection(Metric.DIRECTION_WORST)
1290        .setQualitative(false)
1291        .setDomain(DOMAIN_DESIGN)
1292        .setFormula(new SumChildValuesFormula(false))
1293        .create();
1294    
1295      public static final String PACKAGE_FEEDBACK_EDGES_KEY = "package_feedback_edges";
1296      public static final Metric PACKAGE_FEEDBACK_EDGES = new Metric.Builder(PACKAGE_FEEDBACK_EDGES_KEY, "Package dependencies to cut", Metric.ValueType.INT)
1297        .setDescription("Package dependencies to cut")
1298        .setDirection(Metric.DIRECTION_WORST)
1299        .setQualitative(false)
1300        .setDomain(DOMAIN_DESIGN)
1301        .setFormula(new SumChildValuesFormula(false))
1302        .create();
1303    
1304      public static final String PACKAGE_EDGES_WEIGHT_KEY = "package_edges_weight";
1305      public static final Metric PACKAGE_EDGES_WEIGHT = new Metric.Builder(PACKAGE_EDGES_WEIGHT_KEY, "Package edges weight", Metric.ValueType.INT)
1306        .setDescription("Package edges weight")
1307        .setDirection(Metric.DIRECTION_BETTER)
1308        .setQualitative(false)
1309        .setDomain(DOMAIN_DESIGN)
1310        .setFormula(new SumChildValuesFormula(false))
1311        .setHidden(true)
1312        .create();
1313    
1314      public static final String FILE_CYCLES_KEY = "file_cycles";
1315      public static final Metric FILE_CYCLES = new Metric.Builder(FILE_CYCLES_KEY, "File cycles", Metric.ValueType.INT)
1316        .setDescription("File cycles")
1317        .setDirection(Metric.DIRECTION_WORST)
1318        .setQualitative(true)
1319        .setDomain(DOMAIN_DESIGN)
1320        .setHidden(true)
1321        .create();
1322    
1323      public static final String FILE_TANGLE_INDEX_KEY = "file_tangle_index";
1324      public static final Metric FILE_TANGLE_INDEX = new Metric.Builder(FILE_TANGLE_INDEX_KEY, "File tangle index", Metric.ValueType.PERCENT)
1325        .setDescription("File tangle index")
1326        .setDirection(Metric.DIRECTION_WORST)
1327        .setQualitative(true)
1328        .setDomain(DOMAIN_DESIGN)
1329        .setHidden(true)
1330        .create();
1331    
1332      public static final String FILE_TANGLES_KEY = "file_tangles";
1333      public static final Metric FILE_TANGLES = new Metric.Builder(FILE_TANGLES_KEY, "File tangles", Metric.ValueType.INT)
1334        .setDescription("Files tangles")
1335        .setDirection(Metric.DIRECTION_WORST)
1336        .setQualitative(false)
1337        .setDomain(DOMAIN_DESIGN)
1338        .setHidden(true)
1339        .create();
1340    
1341      public static final String FILE_FEEDBACK_EDGES_KEY = "file_feedback_edges";
1342      public static final Metric FILE_FEEDBACK_EDGES = new Metric.Builder(FILE_FEEDBACK_EDGES_KEY, "Suspect file dependencies", Metric.ValueType.INT)
1343        .setDescription("Suspect file dependencies")
1344        .setDirection(Metric.DIRECTION_WORST)
1345        .setQualitative(false)
1346        .setDomain(DOMAIN_DESIGN)
1347        .setHidden(true)
1348        .create();
1349    
1350      public static final String FILE_EDGES_WEIGHT_KEY = "file_edges_weight";
1351      public static final Metric FILE_EDGES_WEIGHT = new Metric.Builder(FILE_EDGES_WEIGHT_KEY, "File edges weight", Metric.ValueType.INT)
1352        .setDescription("File edges weight")
1353        .setDirection(Metric.DIRECTION_BETTER)
1354        .setQualitative(false)
1355        .setDomain(DOMAIN_DESIGN)
1356        .setHidden(true)
1357        .create();
1358    
1359    
1360      //--------------------------------------------------------------------------------------------------------------------
1361      //
1362      // SCM
1363      // These metrics are computed by the SCM Activity plugin, since version 1.2.
1364      //
1365      //--------------------------------------------------------------------------------------------------------------------
1366    
1367      public static final String SCM_COMMITS_KEY = "commits";
1368      public static final Metric SCM_COMMITS = new Metric.Builder(SCM_COMMITS_KEY, "Commits", Metric.ValueType.INT)
1369        .setDomain(DOMAIN_SCM)
1370        .create();
1371    
1372      public static final String SCM_LAST_COMMIT_DATE_KEY = "last_commit_date";
1373      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 */)
1374        .setDomain(DOMAIN_SCM)
1375        .create();
1376    
1377      public static final String SCM_REVISION_KEY = "revision";
1378      public static final Metric SCM_REVISION = new Metric.Builder(SCM_REVISION_KEY, "Revision", Metric.ValueType.STRING)
1379        .setDomain(DOMAIN_SCM)
1380        .setHidden(true)
1381        .create();
1382    
1383      public static final String SCM_AUTHORS_BY_LINE_KEY = "authors_by_line";
1384      public static final Metric SCM_AUTHORS_BY_LINE = new Metric.Builder(SCM_AUTHORS_BY_LINE_KEY, "Authors by line", Metric.ValueType.DATA)
1385        .setDomain(DOMAIN_SCM)
1386        .create();
1387    
1388      public static final String SCM_REVISIONS_BY_LINE_KEY = "revisions_by_line";
1389      public static final Metric SCM_REVISIONS_BY_LINE = new Metric.Builder(SCM_REVISIONS_BY_LINE_KEY, "Revisions by line", Metric.ValueType.DATA)
1390        .setDomain(DOMAIN_SCM)
1391        .create();
1392    
1393      public static final String SCM_LAST_COMMIT_DATETIMES_BY_LINE_KEY = "last_commit_datetimes_by_line";
1394      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)
1395        .setDomain(DOMAIN_SCM)
1396        .create();
1397    
1398    
1399      //--------------------------------------------------------------------------------------------------------------------
1400      //
1401      // OTHERS
1402      //
1403      //--------------------------------------------------------------------------------------------------------------------
1404      public static final String ALERT_STATUS_KEY = "alert_status";
1405      public static final Metric ALERT_STATUS = new Metric.Builder(ALERT_STATUS_KEY, "Alert", Metric.ValueType.LEVEL)
1406        .setDescription("Alert")
1407        .setDirection(Metric.DIRECTION_BETTER)
1408        .setQualitative(true)
1409        .setDomain(DOMAIN_GENERAL)
1410        .create();
1411    
1412    
1413      public static final String PROFILE_KEY = "profile";
1414      public static final Metric PROFILE = new Metric.Builder(PROFILE_KEY, "Profile", Metric.ValueType.DATA)
1415        .setDescription("Selected quality profile")
1416        .setDomain(DOMAIN_GENERAL)
1417        .create();
1418    
1419      public static final String PROFILE_VERSION_KEY = "profile_version";
1420      public static final Metric PROFILE_VERSION = new Metric.Builder(PROFILE_VERSION_KEY, "Profile version", Metric.ValueType.INT)
1421        .setDescription("Selected quality profile version")
1422        .setQualitative(false)
1423        .setDomain(DOMAIN_GENERAL)
1424        .create();
1425    
1426      public static List<Metric> metrics = Lists.newLinkedList();
1427    
1428      public static List<Metric> getMetrics() {
1429        if (metrics.isEmpty()) {
1430          for (Field field : CoreMetrics.class.getFields()) {
1431            if (Metric.class.isAssignableFrom(field.getType())) {
1432              try {
1433                Metric metric = (Metric) field.get(null);
1434                if (!StringUtils.equals(metric.getDomain(), DOMAIN_RULE_CATEGORIES)) {
1435                  metrics.add(metric);
1436                }
1437              } catch (IllegalAccessException e) {
1438                throw new SonarException("can not load metrics from " + CoreMetrics.class.getSimpleName(), e);
1439              }
1440            }
1441          }
1442        }
1443        return metrics;
1444      }
1445    }