001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2012 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.annotations.Beta;
023    import com.google.common.collect.Lists;
024    import org.apache.commons.lang.StringUtils;
025    import org.sonar.api.resources.Scopes;
026    import org.sonar.api.utils.SonarException;
027    
028    import java.lang.reflect.Field;
029    import java.util.List;
030    
031    /**
032     * @since 1.10
033     */
034    public final class CoreMetrics {
035    
036      private CoreMetrics() {
037        // only static stuff
038      }
039    
040      public static final String DOMAIN_SIZE = "Size";
041      public static final String DOMAIN_TESTS = "Tests";
042      public static final String DOMAIN_INTEGRATION_TESTS = "Integration Tests";
043      public static final String DOMAIN_COMPLEXITY = "Complexity";
044      public static final String DOMAIN_DOCUMENTATION = "Documentation";
045      public static final String DOMAIN_RULES = "Rules";
046      public static final String DOMAIN_SCM = "SCM";
047      public static final String DOMAIN_REVIEWS = "Reviews";
048    
049      /**
050       * @deprecated since 2.5 See SONAR-2007
051       */
052      @Deprecated
053      public static final String DOMAIN_RULE_CATEGORIES = "Rule categories";
054    
055      public static final String DOMAIN_GENERAL = "General";
056      public static final String DOMAIN_DUPLICATION = "Duplication";
057      public static final String DOMAIN_DESIGN = "Design";
058    
059      public static final String LINES_KEY = "lines";
060      public static final Metric LINES = new Metric.Builder(LINES_KEY, "Lines", Metric.ValueType.INT)
061          .setDescription("Lines")
062          .setDirection(Metric.DIRECTION_WORST)
063          .setQualitative(false)
064          .setDomain(DOMAIN_SIZE)
065          .setFormula(new SumChildValuesFormula(false))
066          .create();
067    
068      public static final String GENERATED_LINES_KEY = "generated_lines";
069      public static final Metric GENERATED_LINES = new Metric.Builder(GENERATED_LINES_KEY, "Generated Lines", Metric.ValueType.INT)
070          .setDescription("Number of generated lines")
071          .setDirection(Metric.DIRECTION_WORST)
072          .setQualitative(false)
073          .setDomain(DOMAIN_SIZE)
074          .setBestValue(0.0)
075          .setOptimizedBestValue(true)
076          .setFormula(new SumChildValuesFormula(false))
077          .create();
078    
079      public static final String NCLOC_KEY = "ncloc";
080      public static final Metric NCLOC = new Metric.Builder(NCLOC_KEY, "Lines of code", Metric.ValueType.INT)
081          .setDescription("Non Commenting Lines of Code")
082          .setDirection(Metric.DIRECTION_WORST)
083          .setQualitative(false)
084          .setDomain(DOMAIN_SIZE)
085          .setFormula(new SumChildValuesFormula(false))
086          .create();
087    
088      public static final String GENERATED_NCLOC_KEY = "generated_ncloc";
089      public static final Metric GENERATED_NCLOC = new Metric.Builder(GENERATED_NCLOC_KEY, "Generated lines of code", Metric.ValueType.INT)
090          .setDescription("Generated non Commenting Lines of Code")
091          .setDirection(Metric.DIRECTION_WORST)
092          .setQualitative(false)
093          .setDomain(DOMAIN_SIZE)
094          .setBestValue(0.0)
095          .setOptimizedBestValue(true)
096          .setFormula(new SumChildValuesFormula(false))
097          .create();
098    
099      public static final String CLASSES_KEY = "classes";
100      public static final Metric CLASSES = new Metric.Builder(CLASSES_KEY, "Classes", Metric.ValueType.INT)
101          .setDescription("Classes")
102          .setDirection(Metric.DIRECTION_WORST)
103          .setQualitative(false)
104          .setDomain(DOMAIN_SIZE)
105          .setFormula(new SumChildValuesFormula(false))
106          .create();
107    
108      public static final String FILES_KEY = "files";
109      public static final Metric FILES = new Metric.Builder(FILES_KEY, "Files", Metric.ValueType.INT)
110          .setDescription("Number of files")
111          .setDirection(Metric.DIRECTION_WORST)
112          .setQualitative(false)
113          .setDomain(DOMAIN_SIZE)
114          .create();
115    
116      public static final String DIRECTORIES_KEY = "directories";
117      public static final Metric DIRECTORIES = new Metric.Builder(DIRECTORIES_KEY, "Directories", Metric.ValueType.INT)
118          .setDescription("Directories")
119          .setDirection(Metric.DIRECTION_WORST)
120          .setQualitative(false)
121          .setDomain(DOMAIN_SIZE)
122          .create();
123    
124      public static final String PACKAGES_KEY = "packages";
125      public static final Metric PACKAGES = new Metric.Builder(PACKAGES_KEY, "Packages", Metric.ValueType.INT)
126          .setDescription("Packages")
127          .setDirection(Metric.DIRECTION_WORST)
128          .setQualitative(false)
129          .setDomain(DOMAIN_SIZE)
130          .setFormula(new SumChildValuesFormula(false))
131          .create();
132    
133      public static final String FUNCTIONS_KEY = "functions";
134      public static final Metric FUNCTIONS = new Metric.Builder(FUNCTIONS_KEY, "Methods", Metric.ValueType.INT)
135          .setDescription("Methods")
136          .setDirection(Metric.DIRECTION_WORST)
137          .setQualitative(false)
138          .setDomain(DOMAIN_SIZE)
139          .setFormula(new SumChildValuesFormula(false))
140          .create();
141    
142      public static final String ACCESSORS_KEY = "accessors";
143      public static final Metric ACCESSORS = new Metric.Builder(ACCESSORS_KEY, "Accessors", Metric.ValueType.INT)
144          .setDescription("Accessors")
145          .setDirection(Metric.DIRECTION_WORST)
146          .setQualitative(false)
147          .setDomain(DOMAIN_SIZE)
148          .setFormula(new SumChildValuesFormula(false))
149          .create();
150    
151      /**
152       * @deprecated since Sonar 2.14 - See SONAR-3239
153       */
154      @Deprecated
155      public static final String PARAGRAPHS_KEY = "paragraphs";
156      /**
157       * @deprecated since Sonar 2.14 - See SONAR-3239
158       */
159      @Deprecated
160      public static final Metric PARAGRAPHS = new Metric.Builder(PARAGRAPHS_KEY, "Paragraphs", Metric.ValueType.INT)
161          .setDescription("Number of paragraphs")
162          .setDirection(Metric.DIRECTION_WORST)
163          .setQualitative(false)
164          .setDomain(DOMAIN_SIZE)
165          .setFormula(new SumChildValuesFormula(false))
166          .create();
167    
168      public static final String STATEMENTS_KEY = "statements";
169      public static final Metric STATEMENTS = new Metric.Builder(STATEMENTS_KEY, "Statements", Metric.ValueType.INT)
170          .setDescription("Number of statements")
171          .setDirection(Metric.DIRECTION_WORST)
172          .setQualitative(false)
173          .setDomain(DOMAIN_SIZE)
174          .setFormula(new SumChildValuesFormula(false))
175          .create();
176    
177      public static final String PUBLIC_API_KEY = "public_api";
178      public static final Metric PUBLIC_API = new Metric.Builder(PUBLIC_API_KEY, "Public API", Metric.ValueType.INT)
179          .setDescription("Public API")
180          .setDirection(Metric.DIRECTION_WORST)
181          .setQualitative(false)
182          .setDomain(DOMAIN_SIZE)
183          .setFormula(new SumChildValuesFormula(false))
184          .create();
185    
186      /**
187       * @since 3.0
188       */
189      public static final String PROJECTS_KEY = "projects";
190    
191      /**
192       * @since 3.0
193       */
194      public static final Metric PROJECTS = new Metric.Builder(PROJECTS_KEY, "Projects", Metric.ValueType.INT)
195          .setDescription("Number of projects")
196          .setDirection(Metric.DIRECTION_WORST)
197          .setQualitative(false)
198          .setDomain(DOMAIN_SIZE)
199          .create();
200    
201      //--------------------------------------------------------------------------------------------------------------------
202      //
203      // DOCUMENTATION
204      //
205      //--------------------------------------------------------------------------------------------------------------------
206    
207      public static final String COMMENT_LINES_KEY = "comment_lines";
208      public static final Metric COMMENT_LINES = new Metric.Builder(COMMENT_LINES_KEY, "Comment lines", Metric.ValueType.INT)
209          .setDescription("Number of comment lines")
210          .setDirection(Metric.DIRECTION_BETTER)
211          .setQualitative(false)
212          .setDomain(DOMAIN_DOCUMENTATION)
213          .setFormula(new SumChildValuesFormula(false))
214          .create();
215    
216      public static final String COMMENT_LINES_DENSITY_KEY = "comment_lines_density";
217      public static final Metric COMMENT_LINES_DENSITY = new Metric.Builder(COMMENT_LINES_DENSITY_KEY, "Comments (%)", Metric.ValueType.PERCENT)
218          .setDescription("Comments balanced by ncloc + comment lines")
219          .setDirection(Metric.DIRECTION_BETTER)
220          .setQualitative(true)
221          .setDomain(DOMAIN_DOCUMENTATION)
222          .create();
223    
224      public static final String COMMENT_BLANK_LINES_KEY = "comment_blank_lines";
225      public static final Metric COMMENT_BLANK_LINES = new Metric.Builder(COMMENT_BLANK_LINES_KEY, "Blank comments", Metric.ValueType.INT)
226          .setDescription("Comments that do not contain comments")
227          .setDirection(Metric.DIRECTION_WORST)
228          .setQualitative(false)
229          .setDomain(DOMAIN_DOCUMENTATION)
230          .setFormula(new SumChildValuesFormula(false))
231          .setBestValue(0.0)
232          .setOptimizedBestValue(true)
233          .create();
234    
235      public static final String PUBLIC_DOCUMENTED_API_DENSITY_KEY = "public_documented_api_density";
236      public static final Metric PUBLIC_DOCUMENTED_API_DENSITY = new Metric.Builder(PUBLIC_DOCUMENTED_API_DENSITY_KEY, "Public documented API (%)", Metric.ValueType.PERCENT)
237          .setDescription("Public documented classes and methods balanced by ncloc")
238          .setDirection(Metric.DIRECTION_BETTER)
239          .setQualitative(true)
240          .setDomain(DOMAIN_DOCUMENTATION)
241          .setWorstValue(0.0)
242          .setBestValue(100.0)
243          .setOptimizedBestValue(true)
244          .create();
245    
246      public static final String PUBLIC_UNDOCUMENTED_API_KEY = "public_undocumented_api";
247      public static final Metric PUBLIC_UNDOCUMENTED_API = new Metric.Builder(PUBLIC_UNDOCUMENTED_API_KEY, "Public undocumented API", Metric.ValueType.INT)
248          .setDescription("Public undocumented classes, methods and variables")
249          .setDirection(Metric.DIRECTION_WORST)
250          .setQualitative(true)
251          .setDomain(DOMAIN_DOCUMENTATION)
252          .setBestValue(0.0)
253          .setDirection(Metric.DIRECTION_WORST)
254          .setOptimizedBestValue(true)
255          .setFormula(new SumChildValuesFormula(false))
256          .create();
257    
258      public static final String COMMENTED_OUT_CODE_LINES_KEY = "commented_out_code_lines";
259      public static final Metric COMMENTED_OUT_CODE_LINES = new Metric.Builder(COMMENTED_OUT_CODE_LINES_KEY, "Commented-out LOC", Metric.ValueType.INT)
260          .setDescription("Commented lines of code")
261          .setDirection(Metric.DIRECTION_WORST)
262          .setQualitative(true)
263          .setDomain(DOMAIN_DOCUMENTATION)
264          .setFormula(new SumChildValuesFormula(false))
265          .setBestValue(0.0)
266          .setOptimizedBestValue(true)
267          .create();
268    
269    
270      //--------------------------------------------------------------------------------------------------------------------
271      //
272      // COMPLEXITY
273      //
274      //--------------------------------------------------------------------------------------------------------------------
275    
276      public static final String COMPLEXITY_KEY = "complexity";
277      public static final Metric COMPLEXITY = new Metric.Builder(COMPLEXITY_KEY, "Complexity", Metric.ValueType.INT)
278          .setDescription("Cyclomatic complexity")
279          .setDirection(Metric.DIRECTION_WORST)
280          .setQualitative(false)
281          .setDomain(DOMAIN_COMPLEXITY)
282          .setFormula(new SumChildValuesFormula(false))
283          .create();
284    
285      public static final String CLASS_COMPLEXITY_KEY = "class_complexity";
286      public static final Metric CLASS_COMPLEXITY = new Metric.Builder(CLASS_COMPLEXITY_KEY, "Complexity /class", Metric.ValueType.FLOAT)
287          .setDescription("Complexity average by class")
288          .setDirection(Metric.DIRECTION_WORST)
289          .setQualitative(true)
290          .setDomain(DOMAIN_COMPLEXITY)
291          .setFormula(AverageFormula.create(CoreMetrics.COMPLEXITY, CoreMetrics.CLASSES))
292          .create();
293    
294      public static final String FUNCTION_COMPLEXITY_KEY = "function_complexity";
295      public static final Metric FUNCTION_COMPLEXITY = new Metric.Builder(FUNCTION_COMPLEXITY_KEY, "Complexity /method", Metric.ValueType.FLOAT)
296          .setDescription("Complexity average by method")
297          .setDirection(Metric.DIRECTION_WORST)
298          .setQualitative(true)
299          .setDomain(DOMAIN_COMPLEXITY)
300          .setFormula(AverageFormula.create(CoreMetrics.COMPLEXITY, CoreMetrics.FUNCTIONS))
301          .create();
302    
303      public static final String FILE_COMPLEXITY_KEY = "file_complexity";
304      public static final Metric FILE_COMPLEXITY = new Metric.Builder(FILE_COMPLEXITY_KEY, "Complexity /file", Metric.ValueType.FLOAT)
305          .setDescription("Complexity average by file")
306          .setDirection(Metric.DIRECTION_WORST)
307          .setQualitative(true)
308          .setDomain(DOMAIN_COMPLEXITY)
309          .setFormula(AverageFormula.create(CoreMetrics.COMPLEXITY, CoreMetrics.FILES))
310          .create();
311    
312      /**
313       * @deprecated since Sonar 2.14 - See SONAR-3239
314       */
315      @Deprecated
316      public static final String PARAGRAPH_COMPLEXITY_KEY = "paragraph_complexity";
317    
318      /**
319       * @deprecated since Sonar 2.14 - See SONAR-3239
320       */
321      @Deprecated
322      public static final Metric PARAGRAPH_COMPLEXITY = new Metric.Builder(PARAGRAPH_COMPLEXITY_KEY, "Complexity /paragraph", Metric.ValueType.FLOAT)
323          .setDescription("Complexity average by paragraph")
324          .setDirection(Metric.DIRECTION_WORST)
325          .setQualitative(true)
326          .setDomain(DOMAIN_COMPLEXITY)
327          .setFormula(AverageFormula.create(CoreMetrics.COMPLEXITY, CoreMetrics.PARAGRAPHS))
328          .create();
329    
330      /**
331       * @deprecated in 3.0 - see SONAR-3289
332       */
333      @Deprecated
334      public static final String CLASS_COMPLEXITY_DISTRIBUTION_KEY = "class_complexity_distribution";
335    
336      /**
337       * @deprecated in 3.0 - see SONAR-3289
338       */
339      @Deprecated
340      public static final Metric CLASS_COMPLEXITY_DISTRIBUTION = new Metric.Builder(CLASS_COMPLEXITY_DISTRIBUTION_KEY, "Classes distribution /complexity", Metric.ValueType.DISTRIB)
341          .setDescription("Classes distribution /complexity")
342          .setDirection(Metric.DIRECTION_NONE)
343          .setQualitative(true)
344          .setDomain(DOMAIN_COMPLEXITY)
345          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
346          .create();
347    
348      public static final String FUNCTION_COMPLEXITY_DISTRIBUTION_KEY = "function_complexity_distribution";
349      public static final Metric FUNCTION_COMPLEXITY_DISTRIBUTION = new Metric.Builder(FUNCTION_COMPLEXITY_DISTRIBUTION_KEY, "Functions distribution /complexity", Metric.ValueType.DISTRIB)
350          .setDescription("Functions distribution /complexity")
351          .setDirection(Metric.DIRECTION_NONE)
352          .setQualitative(true)
353          .setDomain(DOMAIN_COMPLEXITY)
354          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
355          .create();
356    
357      public static final String FILE_COMPLEXITY_DISTRIBUTION_KEY = "file_complexity_distribution";
358      public static final Metric FILE_COMPLEXITY_DISTRIBUTION = new Metric.Builder(FILE_COMPLEXITY_DISTRIBUTION_KEY, "Files distribution /complexity", Metric.ValueType.DISTRIB)
359          .setDescription("Files distribution /complexity")
360          .setDirection(Metric.DIRECTION_NONE)
361          .setQualitative(true)
362          .setDomain(DOMAIN_COMPLEXITY)
363          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
364          .create();
365    
366      /**
367       * @deprecated since Sonar 2.14 - See SONAR-3239
368       */
369      @Deprecated
370      public static final String PARAGRAPH_COMPLEXITY_DISTRIBUTION_KEY = "paragraph_complexity_distribution";
371      /**
372       * @deprecated since Sonar 2.14 - See SONAR-3239
373       */
374      @Deprecated
375      public static final Metric PARAGRAPH_COMPLEXITY_DISTRIBUTION = new Metric.Builder(PARAGRAPH_COMPLEXITY_DISTRIBUTION_KEY, "Paragraph distribution /complexity", Metric.ValueType.DISTRIB)
376          .setDescription("Paragraph distribution /complexity")
377          .setDirection(Metric.DIRECTION_NONE)
378          .setQualitative(true)
379          .setDomain(DOMAIN_COMPLEXITY)
380          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
381          .create();
382    
383      //--------------------------------------------------------------------------------------------------------------------
384      //
385      // UNIT TESTS
386      //
387      //--------------------------------------------------------------------------------------------------------------------
388    
389      public static final String TESTS_KEY = "tests";
390    
391      /**
392       * Value of measure for this metric can be saved from Sensor, taking into account following rules:
393       * <ul>
394       * <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>
395       * <li>If tool has been activated, but there was no unit tests to run, then zero value should be saved for project.</li>
396       * <li>Non-zero value should be saved for resources representing tests. And Sonar provides default Decorator, which will decorate parent resources.</li>
397       * <li>Should include {@link #TEST_FAILURES} and {@link #TEST_ERRORS}, but should not include {@link #SKIPPED_TESTS}.</li>
398       * </ul>
399       */
400      public static final Metric TESTS = new Metric.Builder(TESTS_KEY, "Unit tests", Metric.ValueType.INT)
401          .setDescription("Number of unit tests")
402          .setDirection(Metric.DIRECTION_WORST)
403          .setQualitative(false)
404          .setDomain(DOMAIN_TESTS)
405          .create();
406    
407      public static final String TEST_EXECUTION_TIME_KEY = "test_execution_time";
408      public static final Metric TEST_EXECUTION_TIME = new Metric.Builder(TEST_EXECUTION_TIME_KEY, "Unit tests duration", Metric.ValueType.MILLISEC)
409          .setDescription("Execution duration of unit tests")
410          .setDirection(Metric.DIRECTION_WORST)
411          .setQualitative(false)
412          .setDomain(DOMAIN_TESTS)
413          .create();
414    
415      public static final String TEST_ERRORS_KEY = "test_errors";
416      public static final Metric TEST_ERRORS = new Metric.Builder(TEST_ERRORS_KEY, "Unit test errors", Metric.ValueType.INT)
417          .setDescription("Number of unit test errors")
418          .setDirection(Metric.DIRECTION_WORST)
419          .setQualitative(true)
420          .setDomain(DOMAIN_TESTS)
421          .setBestValue(0.0)
422          .setOptimizedBestValue(true)
423          .create();
424    
425      public static final String SKIPPED_TESTS_KEY = "skipped_tests";
426      public static final Metric SKIPPED_TESTS = new Metric.Builder(SKIPPED_TESTS_KEY, "Skipped unit tests", Metric.ValueType.INT)
427          .setDescription("Number of skipped unit tests")
428          .setDirection(Metric.DIRECTION_WORST)
429          .setQualitative(true)
430          .setDomain(DOMAIN_TESTS)
431          .setBestValue(0.0)
432          .setOptimizedBestValue(true)
433          .create();
434    
435      public static final String TEST_FAILURES_KEY = "test_failures";
436      public static final Metric TEST_FAILURES = new Metric.Builder(TEST_FAILURES_KEY, "Unit test failures", Metric.ValueType.INT)
437          .setDescription("Number of unit test failures")
438          .setDirection(Metric.DIRECTION_WORST)
439          .setQualitative(true)
440          .setDomain(DOMAIN_TESTS)
441          .setBestValue(0.0)
442          .setOptimizedBestValue(true)
443          .create();
444    
445      public static final String TEST_SUCCESS_DENSITY_KEY = "test_success_density";
446      public static final Metric TEST_SUCCESS_DENSITY = new Metric.Builder(TEST_SUCCESS_DENSITY_KEY, "Unit test success (%)", Metric.ValueType.PERCENT)
447          .setDescription("Density of successful unit tests")
448          .setDirection(Metric.DIRECTION_BETTER)
449          .setQualitative(true)
450          .setDomain(DOMAIN_TESTS)
451          .setWorstValue(0.0)
452          .setBestValue(100.0)
453          .setOptimizedBestValue(true)
454          .create();
455    
456      public static final String TEST_DATA_KEY = "test_data";
457      public static final Metric TEST_DATA = new Metric.Builder(TEST_DATA_KEY, "Unit tests details", Metric.ValueType.DATA)
458          .setDescription("Unit tests details")
459          .setDirection(Metric.DIRECTION_WORST)
460          .setDomain(DOMAIN_TESTS)
461          .create();
462    
463      public static final String COVERAGE_KEY = "coverage";
464      public static final Metric COVERAGE = new Metric.Builder(COVERAGE_KEY, "Coverage", Metric.ValueType.PERCENT)
465          .setDescription("Coverage by unit tests")
466          .setDirection(Metric.DIRECTION_BETTER)
467          .setQualitative(true)
468          .setDomain(DOMAIN_TESTS)
469          .setWorstValue(0.0)
470          .setBestValue(100.0)
471          .create();
472    
473      public static final String NEW_COVERAGE_KEY = "new_coverage";
474      public static final Metric NEW_COVERAGE = new Metric.Builder(NEW_COVERAGE_KEY, "New coverage", Metric.ValueType.PERCENT)
475          .setDescription("Coverage of new/changed code")
476          .setDirection(Metric.DIRECTION_BETTER)
477          .setQualitative(true)
478          .setDomain(DOMAIN_TESTS)
479          .setWorstValue(0.0)
480          .setBestValue(100.0)
481          .setDeleteHistoricalData(true)
482          .create();
483    
484      public static final String LINES_TO_COVER_KEY = "lines_to_cover";
485    
486      /**
487       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
488       */
489      public static final Metric LINES_TO_COVER = new Metric.Builder(LINES_TO_COVER_KEY, "Lines to cover", Metric.ValueType.INT)
490          .setDescription("Lines to cover")
491          .setDirection(Metric.DIRECTION_BETTER)
492          .setQualitative(false)
493          .setDomain(DOMAIN_TESTS)
494          .setFormula(new SumChildValuesFormula(false))
495          .create();
496    
497      public static final String NEW_LINES_TO_COVER_KEY = "new_lines_to_cover";
498      public static final Metric NEW_LINES_TO_COVER = new Metric.Builder(NEW_LINES_TO_COVER_KEY, "New lines to cover", Metric.ValueType.INT)
499          .setDescription("New lines to cover")
500          .setDirection(Metric.DIRECTION_WORST)
501          .setQualitative(false)
502          .setDomain(DOMAIN_TESTS)
503          .setFormula(new SumChildValuesFormula(false))
504          .setDeleteHistoricalData(true)
505          .create();
506    
507      public static final String UNCOVERED_LINES_KEY = "uncovered_lines";
508    
509      /**
510       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
511       */
512      public static final Metric UNCOVERED_LINES = new Metric.Builder(UNCOVERED_LINES_KEY, "Uncovered lines", Metric.ValueType.INT)
513          .setDescription("Uncovered lines")
514          .setDirection(Metric.DIRECTION_WORST)
515          .setDomain(DOMAIN_TESTS)
516          .setFormula(new SumChildValuesFormula(false))
517          .setBestValue(0.0)
518          .create();
519    
520      public static final String NEW_UNCOVERED_LINES_KEY = "new_uncovered_lines";
521      public static final Metric NEW_UNCOVERED_LINES = new Metric.Builder(NEW_UNCOVERED_LINES_KEY, "New uncovered lines", Metric.ValueType.INT)
522          .setDescription("New uncovered lines")
523          .setDirection(Metric.DIRECTION_WORST)
524          .setDomain(DOMAIN_TESTS)
525          .setFormula(new SumChildValuesFormula(false))
526          .setBestValue(0.0)
527          .setDeleteHistoricalData(true)
528          .create();
529    
530      public static final String LINE_COVERAGE_KEY = "line_coverage";
531      public static final Metric LINE_COVERAGE = new Metric.Builder(LINE_COVERAGE_KEY, "Line coverage", Metric.ValueType.PERCENT)
532          .setDescription("Line coverage")
533          .setDirection(Metric.DIRECTION_BETTER)
534          .setQualitative(true)
535          .setDomain(DOMAIN_TESTS)
536          .setWorstValue(0.0)
537          .setBestValue(100.0)
538          .create();
539    
540      public static final String NEW_LINE_COVERAGE_KEY = "new_line_coverage";
541      public static final Metric NEW_LINE_COVERAGE = new Metric.Builder(NEW_LINE_COVERAGE_KEY, "New line coverage", Metric.ValueType.PERCENT)
542          .setDescription("Line coverage of added/changed code")
543          .setDirection(Metric.DIRECTION_BETTER)
544          .setQualitative(true)
545          .setWorstValue(0.0)
546          .setBestValue(100.0)
547          .setDomain(DOMAIN_TESTS)
548        .setDeleteHistoricalData(true)
549          .create();
550    
551      public static final String COVERAGE_LINE_HITS_DATA_KEY = "coverage_line_hits_data";
552    
553      /**
554       * Key-value pairs, where key - is a number of line, and value - is a number of hits for this line.
555       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
556       */
557      public static final Metric COVERAGE_LINE_HITS_DATA = new Metric.Builder(COVERAGE_LINE_HITS_DATA_KEY, "Coverage hits by line", Metric.ValueType.DATA)
558          .setDomain(DOMAIN_TESTS)
559          .setDeleteHistoricalData(true)
560          .create();
561    
562      public static final String CONDITIONS_TO_COVER_KEY = "conditions_to_cover";
563    
564      /**
565       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
566       */
567      public static final Metric CONDITIONS_TO_COVER = new Metric.Builder(CONDITIONS_TO_COVER_KEY, "Conditions to cover", Metric.ValueType.INT)
568          .setDescription("Conditions to cover")
569          .setDomain(DOMAIN_TESTS)
570          .setFormula(new SumChildValuesFormula(false))
571          .setHidden(true)
572          .setDeleteHistoricalData(true)
573          .create();
574    
575      public static final String NEW_CONDITIONS_TO_COVER_KEY = "new_conditions_to_cover";
576      public static final Metric NEW_CONDITIONS_TO_COVER = new Metric.Builder(NEW_CONDITIONS_TO_COVER_KEY, "New conditions to cover", Metric.ValueType.INT)
577          .setDescription("New conditions to cover")
578          .setDomain(DOMAIN_TESTS)
579          .setFormula(new SumChildValuesFormula(false))
580          .setDeleteHistoricalData(true)
581          .create();
582    
583      public static final String UNCOVERED_CONDITIONS_KEY = "uncovered_conditions";
584    
585      /**
586       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
587       */
588      public static final Metric UNCOVERED_CONDITIONS = new Metric.Builder(UNCOVERED_CONDITIONS_KEY, "Uncovered conditions", Metric.ValueType.INT)
589          .setDescription("Uncovered conditions")
590          .setDirection(Metric.DIRECTION_WORST)
591          .setDomain(DOMAIN_TESTS)
592          .setFormula(new SumChildValuesFormula(false))
593          .setBestValue(0.0)
594          .create();
595    
596      public static final String NEW_UNCOVERED_CONDITIONS_KEY = "new_uncovered_conditions";
597      public static final Metric NEW_UNCOVERED_CONDITIONS = new Metric.Builder(NEW_UNCOVERED_CONDITIONS_KEY, "New uncovered conditions", Metric.ValueType.INT)
598          .setDescription("New uncovered conditions")
599          .setDirection(Metric.DIRECTION_WORST)
600          .setDomain(DOMAIN_TESTS)
601          .setFormula(new SumChildValuesFormula(false))
602          .setBestValue(0.0)
603          .setDeleteHistoricalData(true)
604          .create();
605    
606      public static final String BRANCH_COVERAGE_KEY = "branch_coverage";
607      public static final Metric BRANCH_COVERAGE = new Metric.Builder(BRANCH_COVERAGE_KEY, "Branch coverage", Metric.ValueType.PERCENT)
608          .setDescription("Branch coverage")
609          .setDirection(Metric.DIRECTION_BETTER)
610          .setQualitative(true)
611          .setDomain(DOMAIN_TESTS)
612          .setWorstValue(0.0)
613          .setBestValue(100.0)
614          .create();
615    
616      public static final String NEW_BRANCH_COVERAGE_KEY = "new_branch_coverage";
617      public static final Metric NEW_BRANCH_COVERAGE = new Metric.Builder(NEW_BRANCH_COVERAGE_KEY, "New branch coverage", Metric.ValueType.PERCENT)
618          .setDescription("Branch coverage of new/changed code")
619          .setDirection(Metric.DIRECTION_BETTER)
620          .setQualitative(true)
621          .setDomain(DOMAIN_TESTS)
622          .setWorstValue(0.0)
623          .setBestValue(100.0)
624          .setDeleteHistoricalData(true)
625          .create();
626    
627      /**
628       * @deprecated in 2.7. Replaced by {@link #CONDITIONS_BY_LINE_KEY} and {@link #COVERED_CONDITIONS_BY_LINE_KEY}
629       */
630      @Deprecated
631      public static final String BRANCH_COVERAGE_HITS_DATA_KEY = "branch_coverage_hits_data";
632    
633      /**
634       * @deprecated in 2.7. Replaced by metrics {@link #CONDITIONS_BY_LINE} and {@link #COVERED_CONDITIONS_BY_LINE}
635       */
636      @Deprecated
637      public static final Metric BRANCH_COVERAGE_HITS_DATA = new Metric.Builder(BRANCH_COVERAGE_HITS_DATA_KEY, "Branch coverage hits", Metric.ValueType.DATA)
638          .setDomain(DOMAIN_TESTS)
639          .setDeleteHistoricalData(true)
640          .create();
641    
642      public static final String CONDITIONS_BY_LINE_KEY = "conditions_by_line";
643    
644      /**
645       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
646       *
647       * @since 2.7
648       */
649      public static final Metric CONDITIONS_BY_LINE = new Metric.Builder(CONDITIONS_BY_LINE_KEY, "Conditions by line", Metric.ValueType.DATA)
650          .setDomain(DOMAIN_TESTS)
651          .setDeleteHistoricalData(true)
652          .create();
653    
654      public static final String COVERED_CONDITIONS_BY_LINE_KEY = "covered_conditions_by_line";
655    
656      /**
657       * Use {@link CoverageMeasuresBuilder} to build measure for this metric.
658       *
659       * @since 2.7
660       */
661      public static final Metric COVERED_CONDITIONS_BY_LINE = new Metric.Builder(COVERED_CONDITIONS_BY_LINE_KEY, "Covered conditions by line", Metric.ValueType.DATA)
662          .setDomain(DOMAIN_TESTS)
663          .setDeleteHistoricalData(true)
664          .create();
665    
666    
667      //--------------------------------------------------------------------------------------------------------------------
668      //
669      // INTEGRATION TESTS
670      //
671      //--------------------------------------------------------------------------------------------------------------------
672    
673      /**
674       * @since 2.12
675       */
676      public static final String IT_COVERAGE_KEY = "it_coverage";
677    
678      /**
679       * @since 2.12
680       */
681      public static final Metric IT_COVERAGE = new Metric.Builder(IT_COVERAGE_KEY, "IT Coverage", Metric.ValueType.PERCENT)
682          .setDescription("Coverage by integration tests")
683          .setDirection(Metric.DIRECTION_BETTER)
684          .setQualitative(true)
685          .setDomain(DOMAIN_INTEGRATION_TESTS)
686          .setWorstValue(0.0)
687          .setBestValue(100.0)
688          .create();
689    
690      /**
691       * @since 2.12
692       */
693      public static final String NEW_IT_COVERAGE_KEY = "new_it_coverage";
694    
695      /**
696       * @since 2.12
697       */
698      public static final Metric NEW_IT_COVERAGE = new Metric.Builder(NEW_IT_COVERAGE_KEY, "New Coverage by IT", Metric.ValueType.PERCENT)
699          .setDescription("Integration Tests Coverage of new/changed code")
700          .setDirection(Metric.DIRECTION_BETTER)
701          .setQualitative(true)
702          .setDomain(DOMAIN_INTEGRATION_TESTS)
703          .setWorstValue(0.0)
704          .setBestValue(100.0)
705          .setDeleteHistoricalData(true)
706          .create();
707    
708      /**
709       * @since 2.12
710       */
711      public static final String IT_LINES_TO_COVER_KEY = "it_lines_to_cover";
712    
713      /**
714       * @since 2.12
715       */
716      public static final Metric IT_LINES_TO_COVER = new Metric.Builder(IT_LINES_TO_COVER_KEY, "IT Lines to Cover", Metric.ValueType.INT)
717          .setDescription("Lines to cover by Integration Tests")
718          .setDirection(Metric.DIRECTION_BETTER)
719          .setDomain(DOMAIN_INTEGRATION_TESTS)
720          .setQualitative(false)
721          .setFormula(new SumChildValuesFormula(false))
722          .setHidden(true)
723          .setDeleteHistoricalData(true)
724          .create();
725    
726      /**
727       * @since 2.12
728       */
729      public static final String NEW_IT_LINES_TO_COVER_KEY = "new_it_lines_to_cover";
730    
731      /**
732       * @since 2.12
733       */
734      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)
735          .setDescription("New lines to cover by Integration Tests")
736          .setDirection(Metric.DIRECTION_WORST)
737          .setQualitative(false)
738          .setDomain(DOMAIN_INTEGRATION_TESTS)
739          .setFormula(new SumChildValuesFormula(false))
740          .setDeleteHistoricalData(true)
741          .create();
742    
743      /**
744       * @since 2.12
745       */
746      public static final String IT_UNCOVERED_LINES_KEY = "it_uncovered_lines";
747    
748      /**
749       * @since 2.12
750       */
751      public static final Metric IT_UNCOVERED_LINES = new Metric.Builder(IT_UNCOVERED_LINES_KEY, "IT Uncovered Lines", Metric.ValueType.INT)
752          .setDescription("IT uncovered lines")
753          .setDirection(Metric.DIRECTION_WORST)
754          .setQualitative(false)
755          .setDomain(DOMAIN_INTEGRATION_TESTS)
756          .setFormula(new SumChildValuesFormula(false))
757          .create();
758    
759      /**
760       * @since 2.12
761       */
762      public static final String NEW_IT_UNCOVERED_LINES_KEY = "new_it_uncovered_lines";
763    
764      /**
765       * @since 2.12
766       */
767      public static final Metric NEW_IT_UNCOVERED_LINES = new Metric.Builder(NEW_IT_UNCOVERED_LINES_KEY, "New Uncovered Lines by IT", Metric.ValueType.INT)
768          .setDescription("New uncovered lines by Integration Tests")
769          .setDirection(Metric.DIRECTION_WORST)
770          .setDomain(DOMAIN_INTEGRATION_TESTS)
771          .setFormula(new SumChildValuesFormula(false))
772          .setBestValue(0.0)
773          .setDeleteHistoricalData(true)
774          .create();
775    
776      /**
777       * @since 2.12
778       */
779      public static final String IT_LINE_COVERAGE_KEY = "it_line_coverage";
780    
781      /**
782       * @since 2.12
783       */
784      public static final Metric IT_LINE_COVERAGE = new Metric.Builder(IT_LINE_COVERAGE_KEY, "IT Line coverage", Metric.ValueType.PERCENT)
785          .setDescription("IT line coverage")
786          .setDirection(Metric.DIRECTION_BETTER)
787          .setQualitative(true)
788          .setDomain(DOMAIN_INTEGRATION_TESTS)
789          .create();
790    
791      /**
792       * @since 2.12
793       */
794      public static final String NEW_IT_LINE_COVERAGE_KEY = "new_it_line_coverage";
795    
796      /**
797       * @since 2.12
798       */
799      public static final Metric NEW_IT_LINE_COVERAGE = new Metric.Builder(NEW_IT_LINE_COVERAGE_KEY, "New Line Coverage by IT", Metric.ValueType.PERCENT)
800          .setDescription("Line Coverage by Integration Tests of added/changed code")
801          .setDirection(Metric.DIRECTION_BETTER)
802          .setQualitative(true)
803          .setWorstValue(0.0)
804          .setBestValue(100.0)
805          .setDomain(DOMAIN_INTEGRATION_TESTS)
806          .setDeleteHistoricalData(true)
807          .create();
808    
809      /**
810       * @since 2.12
811       */
812      public static final String IT_COVERAGE_LINE_HITS_DATA_KEY = "it_coverage_line_hits_data";
813    
814      /**
815       * @since 2.12
816       */
817      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)
818          .setDescription("IT Code coverage line hits data")
819          .setDirection(Metric.DIRECTION_NONE)
820          .setQualitative(false)
821          .setDomain(DOMAIN_INTEGRATION_TESTS)
822          .setDeleteHistoricalData(true)
823          .create();
824    
825      /**
826       * @since 2.12
827       */
828      public static final String IT_CONDITIONS_TO_COVER_KEY = "it_conditions_to_cover";
829    
830      /**
831       * @since 2.12
832       */
833      public static final Metric IT_CONDITIONS_TO_COVER = new Metric.Builder(IT_CONDITIONS_TO_COVER_KEY, "IT Branches to Cover", Metric.ValueType.INT)
834          .setDescription("IT Conditions to cover")
835          .setDirection(Metric.DIRECTION_BETTER)
836          .setQualitative(false)
837          .setDomain(DOMAIN_INTEGRATION_TESTS)
838          .setFormula(new SumChildValuesFormula(false))
839          .setHidden(true)
840          .setDeleteHistoricalData(true)
841          .create();
842    
843      /**
844       * @since 2.12
845       */
846      public static final String NEW_IT_CONDITIONS_TO_COVER_KEY = "new_it_conditions_to_cover";
847    
848      /**
849       * @since 2.12
850       */
851      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)
852          .setDescription("New conditions to cover by Integration Tests")
853          .setDomain(DOMAIN_INTEGRATION_TESTS)
854          .setFormula(new SumChildValuesFormula(false))
855          .setDeleteHistoricalData(true)
856          .create();
857    
858      /**
859       * @since 2.12
860       */
861      public static final String IT_UNCOVERED_CONDITIONS_KEY = "it_uncovered_conditions";
862    
863      /**
864       * @since 2.12
865       */
866      public static final Metric IT_UNCOVERED_CONDITIONS = new Metric.Builder(IT_UNCOVERED_CONDITIONS_KEY, "IT Uncovered Branches", Metric.ValueType.INT)
867          .setDescription("IT Uncovered conditions")
868          .setDirection(Metric.DIRECTION_WORST)
869          .setDomain(DOMAIN_INTEGRATION_TESTS)
870          .setFormula(new SumChildValuesFormula(false))
871          .create();
872    
873      /**
874       * @since 2.12
875       */
876      public static final String NEW_IT_UNCOVERED_CONDITIONS_KEY = "new_it_uncovered_conditions";
877    
878      /**
879       * @since 2.12
880       */
881      public static final Metric NEW_IT_UNCOVERED_CONDITIONS = new Metric.Builder(NEW_IT_UNCOVERED_CONDITIONS_KEY, "New Uncovered Conditions by IT", Metric.ValueType.INT)
882          .setDescription("New uncovered conditions by Integration Tests")
883          .setDirection(Metric.DIRECTION_WORST)
884          .setDomain(DOMAIN_INTEGRATION_TESTS)
885          .setFormula(new SumChildValuesFormula(false))
886          .setBestValue(0.0)
887          .setDeleteHistoricalData(true)
888          .create();
889    
890      /**
891       * @since 2.12
892       */
893      public static final String IT_BRANCH_COVERAGE_KEY = "it_branch_coverage";
894    
895      /**
896       * @since 2.12
897       */
898      public static final Metric IT_BRANCH_COVERAGE = new Metric.Builder(IT_BRANCH_COVERAGE_KEY, "IT Branch Coverage", Metric.ValueType.PERCENT)
899          .setDescription("IT Branch coverage")
900          .setDirection(Metric.DIRECTION_BETTER)
901          .setQualitative(true)
902          .setDomain(DOMAIN_INTEGRATION_TESTS)
903          .setWorstValue(0.0)
904          .setBestValue(100.0)
905          .create();
906    
907      /**
908       * @since 2.12
909       */
910      public static final String NEW_IT_BRANCH_COVERAGE_KEY = "new_it_branch_coverage";
911    
912      /**
913       * @since 2.12
914       */
915      public static final Metric NEW_IT_BRANCH_COVERAGE = new Metric.Builder(NEW_IT_BRANCH_COVERAGE_KEY, "New Branch Coverage by IT", Metric.ValueType.PERCENT)
916          .setDescription("Branch coverage by Integration Tests of new/changed code")
917          .setDirection(Metric.DIRECTION_BETTER)
918          .setQualitative(true)
919          .setDomain(DOMAIN_INTEGRATION_TESTS)
920          .setWorstValue(0.0)
921          .setBestValue(100.0)
922          .setDeleteHistoricalData(true)
923          .create();
924    
925      /**
926       * @since 2.12
927       */
928      public static final String IT_CONDITIONS_BY_LINE_KEY = "it_conditions_by_line";
929    
930      /**
931       * @since 2.12
932       */
933      public static final Metric IT_CONDITIONS_BY_LINE = new Metric.Builder(IT_CONDITIONS_BY_LINE_KEY, "IT Branches by Line", Metric.ValueType.DATA)
934          .setDomain(DOMAIN_INTEGRATION_TESTS)
935          .setDeleteHistoricalData(true)
936          .create();
937    
938      /**
939       * @since 2.12
940       */
941      public static final String IT_COVERED_CONDITIONS_BY_LINE_KEY = "it_covered_conditions_by_line";
942    
943      /**
944       * @since 2.12
945       */
946      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)
947          .setDomain(DOMAIN_INTEGRATION_TESTS)
948          .setDeleteHistoricalData(true)
949          .create();
950    
951    
952      //--------------------------------------------------------------------------------------------------------------------
953      //
954      // DUPLICATIONS
955      //
956      //--------------------------------------------------------------------------------------------------------------------
957    
958      public static final String DUPLICATED_LINES_KEY = "duplicated_lines";
959      public static final Metric DUPLICATED_LINES = new Metric.Builder(DUPLICATED_LINES_KEY, "Duplicated lines", Metric.ValueType.INT)
960          .setDescription("Duplicated lines")
961          .setDirection(Metric.DIRECTION_WORST)
962          .setQualitative(true)
963          .setDomain(DOMAIN_DUPLICATION)
964          .setBestValue(0.0)
965          .setOptimizedBestValue(true)
966          .create();
967    
968      public static final String DUPLICATED_BLOCKS_KEY = "duplicated_blocks";
969      public static final Metric DUPLICATED_BLOCKS = new Metric.Builder(DUPLICATED_BLOCKS_KEY, "Duplicated blocks", Metric.ValueType.INT)
970          .setDescription("Duplicated blocks")
971          .setDirection(Metric.DIRECTION_WORST)
972          .setQualitative(true)
973          .setDomain(DOMAIN_DUPLICATION)
974          .setBestValue(0.0)
975          .setOptimizedBestValue(true)
976          .create();
977    
978      public static final String DUPLICATED_FILES_KEY = "duplicated_files";
979    
980      /**
981       * For files: if it contains duplicates, then 1, otherwise 0.
982       * For other resources: amount of files under this resource with duplicates.
983       */
984      public static final Metric DUPLICATED_FILES = new Metric.Builder(DUPLICATED_FILES_KEY, "Duplicated files", Metric.ValueType.INT)
985          .setDescription("Duplicated files")
986          .setDirection(Metric.DIRECTION_WORST)
987          .setQualitative(true)
988          .setDomain(DOMAIN_DUPLICATION)
989          .setBestValue(0.0)
990          .setOptimizedBestValue(true)
991          .create();
992    
993      public static final String DUPLICATED_LINES_DENSITY_KEY = "duplicated_lines_density";
994      public static final Metric DUPLICATED_LINES_DENSITY = new Metric.Builder(DUPLICATED_LINES_DENSITY_KEY, "Duplicated lines (%)", Metric.ValueType.PERCENT)
995          .setDescription("Duplicated lines balanced by statements")
996          .setDirection(Metric.DIRECTION_WORST)
997          .setQualitative(true)
998          .setDomain(DOMAIN_DUPLICATION)
999          .setWorstValue(50.0)
1000          .setBestValue(0.0)
1001          .setOptimizedBestValue(true)
1002          .create();
1003    
1004      public static final String DUPLICATIONS_DATA_KEY = "duplications_data";
1005    
1006      /**
1007       * Information about duplications, which is represented as an XML string. There are two formats:
1008       * <ul>
1009       * <li>For Sonar CPD (since 2.12):
1010       * <pre>   {@code
1011       *   <duplications>
1012       *     <!-- Multiple groups: -->
1013       *     <g>
1014       *       <!-- Multiple blocks: -->
1015       *       <b r="[resource key]" s="[first line]" l="[number of lines]" />
1016       *       ...
1017       *     </g>
1018       *     ...
1019       *   </duplications>}</pre>
1020       * </li>
1021       * <li>For PMD CPD (deprecated in 2.14 - see SONAR-3238):
1022       * <pre>   {@code
1023       *   <duplications>
1024       *     <duplication start="[first line]" lines="[number of lines]" target-resource="[resource key]" target-start="[first line in target]" />
1025       *     ...
1026       *   </duplications>
1027       * }</pre>
1028       * Note that this format has following drawbacks:
1029       * <ol>
1030       * <li>assumes that amount of lines is the same for both resources</li>
1031       * <li>duplication can span no more than two resources</li>
1032       * <li>and they both in same project</li>
1033       * </ol>
1034       * </li>
1035       * </ul>
1036       */
1037      public static final Metric DUPLICATIONS_DATA = new Metric.Builder(DUPLICATIONS_DATA_KEY, "Duplications details", Metric.ValueType.DATA)
1038          .setDescription("Duplications details")
1039          .setDirection(Metric.DIRECTION_NONE)
1040          .setQualitative(false)
1041          .setDomain(DOMAIN_DUPLICATION)
1042          .setDeleteHistoricalData(true)
1043          .create();
1044    
1045      //--------------------------------------------------------------------------------------------------------------------
1046      //
1047      // CODING RULES
1048      //
1049      //--------------------------------------------------------------------------------------------------------------------
1050    
1051      /**
1052       * @deprecated since 2.5 See SONAR-2007
1053       */
1054      @Deprecated
1055      public static final String USABILITY_KEY = "usability";
1056    
1057      /**
1058       * @deprecated since 2.5 See SONAR-2007
1059       */
1060      @Deprecated
1061      public static final Metric USABILITY = new Metric(USABILITY_KEY, "Usability", "Usability", Metric.ValueType.PERCENT,
1062          Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
1063    
1064      /**
1065       * @deprecated since 2.5 See SONAR-2007
1066       */
1067      @Deprecated
1068      public static final String RELIABILITY_KEY = "reliability";
1069    
1070      /**
1071       * @deprecated since 2.5 See SONAR-2007
1072       */
1073      @Deprecated
1074      public static final Metric RELIABILITY = new Metric(RELIABILITY_KEY, "Reliability", "Reliability", Metric.ValueType.PERCENT,
1075          Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
1076    
1077      /**
1078       * @deprecated since 2.5 See SONAR-2007
1079       */
1080      @Deprecated
1081      public static final String EFFICIENCY_KEY = "efficiency";
1082    
1083      /**
1084       * @deprecated since 2.5 See SONAR-2007
1085       */
1086      @Deprecated
1087      public static final Metric EFFICIENCY = new Metric(EFFICIENCY_KEY, "Efficiency", "Efficiency", Metric.ValueType.PERCENT,
1088          Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
1089    
1090      /**
1091       * @deprecated since 2.5 See SONAR-2007
1092       */
1093      @Deprecated
1094      public static final String PORTABILITY_KEY = "portability";
1095    
1096      /**
1097       * @deprecated since 2.5 See SONAR-2007
1098       */
1099      @Deprecated
1100      public static final Metric PORTABILITY = new Metric(PORTABILITY_KEY, "Portability", "Portability", Metric.ValueType.PERCENT,
1101          Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
1102    
1103      /**
1104       * @deprecated since 2.5 See SONAR-2007
1105       */
1106      @Deprecated
1107      public static final String MAINTAINABILITY_KEY = "maintainability";
1108    
1109      /**
1110       * @deprecated since 2.5 See SONAR-2007
1111       */
1112      @Deprecated
1113      public static final Metric MAINTAINABILITY = new Metric.Builder(MAINTAINABILITY_KEY, "Maintainability", Metric.ValueType.PERCENT)
1114          .setDescription("Maintainability")
1115          .setDirection(Metric.DIRECTION_BETTER)
1116          .setQualitative(true)
1117          .setDomain(DOMAIN_RULE_CATEGORIES)
1118          .setBestValue(100.0)
1119          .setOptimizedBestValue(true)
1120          .create();
1121    
1122      public static final String WEIGHTED_VIOLATIONS_KEY = "weighted_violations";
1123      public static final Metric WEIGHTED_VIOLATIONS = new Metric.Builder(WEIGHTED_VIOLATIONS_KEY, "Weighted violations", Metric.ValueType.INT)
1124          .setDescription("Weighted Violations")
1125          .setDirection(Metric.DIRECTION_WORST)
1126          .setQualitative(true)
1127          .setDomain(DOMAIN_RULES)
1128          .setBestValue(0.0)
1129          .setOptimizedBestValue(true)
1130          .create();
1131    
1132      public static final String VIOLATIONS_DENSITY_KEY = "violations_density";
1133      public static final Metric VIOLATIONS_DENSITY = new Metric.Builder(VIOLATIONS_DENSITY_KEY, "Rules compliance", Metric.ValueType.PERCENT)
1134          .setDescription("Rules compliance")
1135          .setDirection(Metric.DIRECTION_BETTER)
1136          .setQualitative(true)
1137          .setDomain(DOMAIN_RULES)
1138          .create();
1139    
1140      public static final String VIOLATIONS_KEY = "violations";
1141      public static final Metric VIOLATIONS = new Metric.Builder(VIOLATIONS_KEY, "Violations", Metric.ValueType.INT)
1142          .setDescription("Violations")
1143          .setDirection(Metric.DIRECTION_WORST)
1144          .setQualitative(true)
1145          .setDomain(DOMAIN_RULES)
1146          .setBestValue(0.0)
1147          .setOptimizedBestValue(true)
1148          .create();
1149    
1150      public static final String BLOCKER_VIOLATIONS_KEY = "blocker_violations";
1151      public static final Metric BLOCKER_VIOLATIONS = new Metric.Builder(BLOCKER_VIOLATIONS_KEY, "Blocker violations", Metric.ValueType.INT)
1152          .setDescription("Blocker violations")
1153          .setDirection(Metric.DIRECTION_WORST)
1154          .setQualitative(true)
1155          .setDomain(DOMAIN_RULES)
1156          .setBestValue(0.0)
1157          .setOptimizedBestValue(true)
1158          .create();
1159    
1160      public static final String CRITICAL_VIOLATIONS_KEY = "critical_violations";
1161      public static final Metric CRITICAL_VIOLATIONS = new Metric.Builder(CRITICAL_VIOLATIONS_KEY, "Critical violations", Metric.ValueType.INT)
1162          .setDescription("Critical violations")
1163          .setDirection(Metric.DIRECTION_WORST)
1164          .setQualitative(true)
1165          .setDomain(DOMAIN_RULES)
1166          .setBestValue(0.0)
1167          .setOptimizedBestValue(true)
1168          .create();
1169    
1170      public static final String MAJOR_VIOLATIONS_KEY = "major_violations";
1171      public static final Metric MAJOR_VIOLATIONS = new Metric.Builder(MAJOR_VIOLATIONS_KEY, "Major violations", Metric.ValueType.INT)
1172          .setDescription("Major violations")
1173          .setDirection(Metric.DIRECTION_WORST)
1174          .setQualitative(true)
1175          .setDomain(DOMAIN_RULES)
1176          .setBestValue(0.0)
1177          .setOptimizedBestValue(true)
1178          .create();
1179    
1180      public static final String MINOR_VIOLATIONS_KEY = "minor_violations";
1181      public static final Metric MINOR_VIOLATIONS = new Metric.Builder(MINOR_VIOLATIONS_KEY, "Minor violations", Metric.ValueType.INT)
1182          .setDescription("Minor violations")
1183          .setDirection(Metric.DIRECTION_WORST)
1184          .setQualitative(true)
1185          .setDomain(DOMAIN_RULES)
1186          .setBestValue(0.0)
1187          .setOptimizedBestValue(true)
1188          .create();
1189    
1190      public static final String INFO_VIOLATIONS_KEY = "info_violations";
1191      public static final Metric INFO_VIOLATIONS = new Metric.Builder(INFO_VIOLATIONS_KEY, "Info violations", Metric.ValueType.INT)
1192          .setDescription("Info violations")
1193          .setDirection(Metric.DIRECTION_WORST)
1194          .setQualitative(true)
1195          .setDomain(DOMAIN_RULES)
1196          .setBestValue(0.0)
1197          .setOptimizedBestValue(true)
1198          .create();
1199    
1200      public static final String NEW_VIOLATIONS_KEY = "new_violations";
1201      public static final Metric NEW_VIOLATIONS = new Metric.Builder(NEW_VIOLATIONS_KEY, "New Violations", Metric.ValueType.INT)
1202          .setDescription("New Violations")
1203          .setDirection(Metric.DIRECTION_WORST)
1204          .setQualitative(true)
1205          .setDomain(DOMAIN_RULES)
1206          .setBestValue(0.0)
1207          .setOptimizedBestValue(true)
1208          .setDeleteHistoricalData(true)
1209          .create();
1210    
1211      public static final String NEW_BLOCKER_VIOLATIONS_KEY = "new_blocker_violations";
1212      public static final Metric NEW_BLOCKER_VIOLATIONS = new Metric.Builder(NEW_BLOCKER_VIOLATIONS_KEY, "New Blocker violations", Metric.ValueType.INT)
1213          .setDescription("New Blocker violations")
1214          .setDirection(Metric.DIRECTION_WORST)
1215          .setQualitative(true)
1216          .setDomain(DOMAIN_RULES)
1217          .setBestValue(0.0)
1218          .setOptimizedBestValue(true)
1219          .setDeleteHistoricalData(true)
1220          .create();
1221    
1222      public static final String NEW_CRITICAL_VIOLATIONS_KEY = "new_critical_violations";
1223      public static final Metric NEW_CRITICAL_VIOLATIONS = new Metric.Builder(NEW_CRITICAL_VIOLATIONS_KEY, "New Critical violations", Metric.ValueType.INT)
1224          .setDescription("New Critical violations")
1225          .setDirection(Metric.DIRECTION_WORST)
1226          .setQualitative(true)
1227          .setDomain(DOMAIN_RULES)
1228          .setBestValue(0.0)
1229          .setOptimizedBestValue(true)
1230          .setDeleteHistoricalData(true)
1231          .create();
1232    
1233      public static final String NEW_MAJOR_VIOLATIONS_KEY = "new_major_violations";
1234      public static final Metric NEW_MAJOR_VIOLATIONS = new Metric.Builder(NEW_MAJOR_VIOLATIONS_KEY, "New Major violations", Metric.ValueType.INT)
1235          .setDescription("New Major violations")
1236          .setDirection(Metric.DIRECTION_WORST)
1237          .setQualitative(true)
1238          .setDomain(DOMAIN_RULES)
1239          .setBestValue(0.0)
1240          .setOptimizedBestValue(true)
1241          .setDeleteHistoricalData(true)
1242          .create();
1243    
1244      public static final String NEW_MINOR_VIOLATIONS_KEY = "new_minor_violations";
1245      public static final Metric NEW_MINOR_VIOLATIONS = new Metric.Builder(NEW_MINOR_VIOLATIONS_KEY, "New Minor violations", Metric.ValueType.INT)
1246          .setDescription("New Minor violations")
1247          .setDirection(Metric.DIRECTION_WORST)
1248          .setQualitative(true)
1249          .setDomain(DOMAIN_RULES)
1250          .setBestValue(0.0)
1251          .setOptimizedBestValue(true)
1252          .setDeleteHistoricalData(true)
1253          .create();
1254    
1255      public static final String NEW_INFO_VIOLATIONS_KEY = "new_info_violations";
1256      public static final Metric NEW_INFO_VIOLATIONS = new Metric.Builder(NEW_INFO_VIOLATIONS_KEY, "New Info violations", Metric.ValueType.INT)
1257          .setDescription("New Info violations")
1258          .setDirection(Metric.DIRECTION_WORST)
1259          .setQualitative(true)
1260          .setDomain(DOMAIN_RULES)
1261          .setBestValue(0.0)
1262          .setOptimizedBestValue(true)
1263          .setDeleteHistoricalData(true)
1264          .create();
1265    
1266    
1267      //--------------------------------------------------------------------------------------------------------------------
1268      //
1269      // DESIGN
1270      //
1271      //--------------------------------------------------------------------------------------------------------------------
1272    
1273      public static final String ABSTRACTNESS_KEY = "abstractness";
1274      public static final Metric ABSTRACTNESS = new Metric.Builder(ABSTRACTNESS_KEY, "Abstractness", Metric.ValueType.PERCENT)
1275          .setDescription("Abstractness")
1276          .setDirection(Metric.DIRECTION_NONE)
1277          .setQualitative(false)
1278          .setDomain(DOMAIN_DESIGN)
1279          .create();
1280    
1281      public static final String INSTABILITY_KEY = "instability";
1282      public static final Metric INSTABILITY = new Metric.Builder(INSTABILITY_KEY, "Instability", Metric.ValueType.PERCENT)
1283          .setDescription("Instability")
1284          .setDirection(Metric.DIRECTION_NONE)
1285          .setQualitative(false)
1286          .setDomain(DOMAIN_DESIGN)
1287          .create();
1288    
1289      public static final String DISTANCE_KEY = "distance";
1290      public static final Metric DISTANCE = new Metric.Builder(DISTANCE_KEY, "Distance", Metric.ValueType.FLOAT)
1291          .setDescription("Distance")
1292          .setDirection(Metric.DIRECTION_NONE)
1293          .setQualitative(false)
1294          .setDomain(DOMAIN_DESIGN)
1295          .create();
1296    
1297      public static final String DEPTH_IN_TREE_KEY = "dit";
1298      public static final Metric DEPTH_IN_TREE = new Metric.Builder(DEPTH_IN_TREE_KEY, "Depth in Tree", Metric.ValueType.INT)
1299          .setDescription("Depth in Inheritance Tree")
1300          .setDirection(Metric.DIRECTION_NONE)
1301          .setQualitative(false)
1302          .setDomain(DOMAIN_DESIGN)
1303          .create();
1304    
1305      public static final String NUMBER_OF_CHILDREN_KEY = "noc";
1306      public static final Metric NUMBER_OF_CHILDREN = new Metric.Builder(NUMBER_OF_CHILDREN_KEY, "Number of Children", Metric.ValueType.INT)
1307          .setDescription("Number of Children")
1308          .setDirection(Metric.DIRECTION_NONE)
1309          .setQualitative(false)
1310          .setDomain(DOMAIN_DESIGN)
1311          .create();
1312    
1313      public static final String RFC_KEY = "rfc";
1314      public static final Metric RFC = new Metric.Builder(RFC_KEY, "RFC", Metric.ValueType.INT)
1315          .setDescription("Response for Class")
1316          .setDirection(Metric.DIRECTION_WORST)
1317          .setQualitative(false)
1318          .setDomain(DOMAIN_DESIGN)
1319          .setFormula(new WeightedMeanAggregationFormula(CoreMetrics.FILES, false))
1320          .create();
1321    
1322      public static final String RFC_DISTRIBUTION_KEY = "rfc_distribution";
1323      public static final Metric RFC_DISTRIBUTION = new Metric.Builder(RFC_DISTRIBUTION_KEY, "Class distribution /RFC", Metric.ValueType.DISTRIB)
1324          .setDescription("Class distribution /RFC")
1325          .setDirection(Metric.DIRECTION_NONE)
1326          .setQualitative(true)
1327          .setDomain(DOMAIN_DESIGN)
1328          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
1329          .create();
1330    
1331      public static final String LCOM4_KEY = "lcom4";
1332      public static final Metric LCOM4 = new Metric.Builder(LCOM4_KEY, "LCOM4", Metric.ValueType.FLOAT)
1333          .setDescription("Lack of Cohesion of Methods")
1334          .setDirection(Metric.DIRECTION_WORST)
1335          .setQualitative(true)
1336          .setDomain(DOMAIN_DESIGN)
1337          .setBestValue(1.0)
1338          .setFormula(new WeightedMeanAggregationFormula(CoreMetrics.FILES, false))
1339          .create();
1340    
1341      public static final String LCOM4_BLOCKS_KEY = "lcom4_blocks";
1342      public static final Metric LCOM4_BLOCKS = new Metric.Builder(LCOM4_BLOCKS_KEY, "LCOM4 blocks", Metric.ValueType.DATA)
1343          .setDescription("LCOM4 blocks")
1344          .setDirection(Metric.DIRECTION_NONE)
1345          .setQualitative(false)
1346          .setDomain(DOMAIN_DESIGN)
1347          .setHidden(true)
1348          .setDeleteHistoricalData(true)
1349          .create();
1350    
1351      public static final String LCOM4_DISTRIBUTION_KEY = "lcom4_distribution";
1352      public static final Metric LCOM4_DISTRIBUTION = new Metric.Builder(LCOM4_DISTRIBUTION_KEY, "Class distribution /LCOM4", Metric.ValueType.DISTRIB)
1353          .setDescription("Class distribution /LCOM4")
1354          .setDirection(Metric.DIRECTION_NONE)
1355          .setQualitative(true)
1356          .setDomain(DOMAIN_DESIGN)
1357          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY))
1358          .create();
1359    
1360      public static final String SUSPECT_LCOM4_DENSITY_KEY = "suspect_lcom4_density";
1361      public static final Metric SUSPECT_LCOM4_DENSITY = new Metric.Builder(SUSPECT_LCOM4_DENSITY_KEY, "Suspect LCOM4 density", Metric.ValueType.PERCENT)
1362          .setDescription("Density of classes having LCOM4>1")
1363          .setDirection(Metric.DIRECTION_WORST)
1364          .setQualitative(true)
1365          .setDomain(DOMAIN_DESIGN)
1366          .create();
1367    
1368      public static final String AFFERENT_COUPLINGS_KEY = "ca";
1369      public static final Metric AFFERENT_COUPLINGS = new Metric.Builder(AFFERENT_COUPLINGS_KEY, "Afferent couplings", Metric.ValueType.INT)
1370          .setDescription("Afferent couplings")
1371          .setDirection(Metric.DIRECTION_WORST)
1372          .setQualitative(false)
1373          .setDomain(DOMAIN_DESIGN)
1374          .create();
1375    
1376      public static final String EFFERENT_COUPLINGS_KEY = "ce";
1377      public static final Metric EFFERENT_COUPLINGS = new Metric.Builder(EFFERENT_COUPLINGS_KEY, "Efferent couplings", Metric.ValueType.INT)
1378          .setDescription("Efferent couplings")
1379          .setDirection(Metric.DIRECTION_WORST)
1380          .setQualitative(false)
1381          .setDomain(DOMAIN_DESIGN)
1382          .create();
1383    
1384      public static final String DEPENDENCY_MATRIX_KEY = "dsm";
1385      public static final Metric DEPENDENCY_MATRIX = new Metric.Builder(DEPENDENCY_MATRIX_KEY, "Dependency Matrix", Metric.ValueType.DATA)
1386          .setDescription("Dependency Matrix")
1387          .setDirection(Metric.DIRECTION_NONE)
1388          .setQualitative(false)
1389          .setDomain(DOMAIN_DESIGN)
1390          .setDeleteHistoricalData(true)
1391          .create();
1392    
1393      public static final String PACKAGE_CYCLES_KEY = "package_cycles";
1394      public static final Metric PACKAGE_CYCLES = new Metric.Builder(PACKAGE_CYCLES_KEY, "Package cycles", Metric.ValueType.INT)
1395          .setDescription("Package cycles")
1396          .setDirection(Metric.DIRECTION_WORST)
1397          .setQualitative(true)
1398          .setDomain(DOMAIN_DESIGN)
1399          .setBestValue(0.0)
1400          .setFormula(new SumChildValuesFormula(false))
1401          .create();
1402    
1403      public static final String PACKAGE_TANGLE_INDEX_KEY = "package_tangle_index";
1404      public static final Metric PACKAGE_TANGLE_INDEX = new Metric.Builder(PACKAGE_TANGLE_INDEX_KEY, "Package tangle index", Metric.ValueType.PERCENT)
1405          .setDescription("Package tangle index")
1406          .setDirection(Metric.DIRECTION_WORST)
1407          .setQualitative(true)
1408          .setBestValue(0.0)
1409          .setDomain(DOMAIN_DESIGN)
1410          .create();
1411    
1412      public static final String PACKAGE_TANGLES_KEY = "package_tangles";
1413      public static final Metric PACKAGE_TANGLES = new Metric.Builder(PACKAGE_TANGLES_KEY, "File dependencies to cut", Metric.ValueType.INT)
1414          .setDescription("File dependencies to cut")
1415          .setDirection(Metric.DIRECTION_WORST)
1416          .setQualitative(false)
1417          .setDomain(DOMAIN_DESIGN)
1418          .setFormula(new SumChildValuesFormula(false))
1419          .create();
1420    
1421      public static final String PACKAGE_FEEDBACK_EDGES_KEY = "package_feedback_edges";
1422      public static final Metric PACKAGE_FEEDBACK_EDGES = new Metric.Builder(PACKAGE_FEEDBACK_EDGES_KEY, "Package dependencies to cut", Metric.ValueType.INT)
1423          .setDescription("Package dependencies to cut")
1424          .setDirection(Metric.DIRECTION_WORST)
1425          .setQualitative(false)
1426          .setDomain(DOMAIN_DESIGN)
1427          .setFormula(new SumChildValuesFormula(false))
1428          .setBestValue(0.0)
1429          .create();
1430    
1431      public static final String PACKAGE_EDGES_WEIGHT_KEY = "package_edges_weight";
1432      public static final Metric PACKAGE_EDGES_WEIGHT = new Metric.Builder(PACKAGE_EDGES_WEIGHT_KEY, "Package edges weight", Metric.ValueType.INT)
1433          .setDescription("Package edges weight")
1434          .setDirection(Metric.DIRECTION_BETTER)
1435          .setQualitative(false)
1436          .setDomain(DOMAIN_DESIGN)
1437          .setFormula(new SumChildValuesFormula(false))
1438          .setHidden(true)
1439          .setDeleteHistoricalData(true)
1440          .create();
1441    
1442      public static final String FILE_CYCLES_KEY = "file_cycles";
1443      public static final Metric FILE_CYCLES = new Metric.Builder(FILE_CYCLES_KEY, "File cycles", Metric.ValueType.INT)
1444          .setDescription("File cycles")
1445          .setDirection(Metric.DIRECTION_WORST)
1446          .setQualitative(true)
1447          .setDomain(DOMAIN_DESIGN)
1448          .setHidden(true)
1449          .setDeleteHistoricalData(true)
1450          .setBestValue(0.0)
1451          .create();
1452    
1453      public static final String FILE_TANGLE_INDEX_KEY = "file_tangle_index";
1454      public static final Metric FILE_TANGLE_INDEX = new Metric.Builder(FILE_TANGLE_INDEX_KEY, "File tangle index", Metric.ValueType.PERCENT)
1455          .setDescription("File tangle index")
1456          .setDirection(Metric.DIRECTION_WORST)
1457          .setQualitative(true)
1458          .setDomain(DOMAIN_DESIGN)
1459          .setHidden(true)
1460          .setDeleteHistoricalData(true)
1461          .setBestValue(0.0)
1462          .create();
1463    
1464      public static final String FILE_TANGLES_KEY = "file_tangles";
1465      public static final Metric FILE_TANGLES = new Metric.Builder(FILE_TANGLES_KEY, "File tangles", Metric.ValueType.INT)
1466          .setDescription("Files tangles")
1467          .setDirection(Metric.DIRECTION_WORST)
1468          .setQualitative(false)
1469          .setDomain(DOMAIN_DESIGN)
1470          .setHidden(true)
1471          .setDeleteHistoricalData(true)
1472          .create();
1473    
1474      public static final String FILE_FEEDBACK_EDGES_KEY = "file_feedback_edges";
1475      public static final Metric FILE_FEEDBACK_EDGES = new Metric.Builder(FILE_FEEDBACK_EDGES_KEY, "Suspect file dependencies", Metric.ValueType.INT)
1476          .setDescription("Suspect file dependencies")
1477          .setDirection(Metric.DIRECTION_WORST)
1478          .setQualitative(false)
1479          .setDomain(DOMAIN_DESIGN)
1480          .setHidden(true)
1481          .setDeleteHistoricalData(true)
1482          .setBestValue(0.0)
1483          .create();
1484    
1485      public static final String FILE_EDGES_WEIGHT_KEY = "file_edges_weight";
1486      public static final Metric FILE_EDGES_WEIGHT = new Metric.Builder(FILE_EDGES_WEIGHT_KEY, "File edges weight", Metric.ValueType.INT)
1487          .setDescription("File edges weight")
1488          .setDirection(Metric.DIRECTION_BETTER)
1489          .setQualitative(false)
1490          .setDomain(DOMAIN_DESIGN)
1491          .setHidden(true)
1492          .setDeleteHistoricalData(true)
1493          .create();
1494    
1495    
1496      //--------------------------------------------------------------------------------------------------------------------
1497      //
1498      // SCM
1499      // These metrics are computed by the SCM Activity plugin, since version 1.2 and introduced here since version 2.7.
1500      //
1501      //--------------------------------------------------------------------------------------------------------------------
1502    
1503      /**
1504       * @since 2.7
1505       */
1506      public static final String SCM_COMMITS_KEY = "commits";
1507    
1508      /**
1509       * @since 2.7
1510       */
1511      public static final Metric SCM_COMMITS = new Metric.Builder(SCM_COMMITS_KEY, "Commits", Metric.ValueType.INT)
1512          .setDomain(DOMAIN_SCM)
1513          .create();
1514    
1515      /**
1516       * @since 2.7
1517       */
1518      public static final String SCM_LAST_COMMIT_DATE_KEY = "last_commit_date";
1519    
1520      /**
1521       * Date of last commit, which is represented as string in format {@link org.sonar.api.utils.DateUtils#DATE_FORMAT}.
1522       *
1523       * @since 2.7
1524       */
1525      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 */)
1526          .setDomain(DOMAIN_SCM)
1527          .create();
1528    
1529      /**
1530       * @since 2.7
1531       */
1532      public static final String SCM_REVISION_KEY = "revision";
1533    
1534      /**
1535       * @since 2.7
1536       */
1537      public static final Metric SCM_REVISION = new Metric.Builder(SCM_REVISION_KEY, "Revision", Metric.ValueType.STRING)
1538          .setDomain(DOMAIN_SCM)
1539          .setHidden(true)
1540          .create();
1541    
1542      /**
1543       * @since 2.7
1544       */
1545      public static final String SCM_AUTHORS_BY_LINE_KEY = "authors_by_line";
1546    
1547      /**
1548       * Key-value pairs, where key - is a number of line, and value - is an author for this line.
1549       *
1550       * @see org.sonar.api.utils.KeyValueFormat#formatIntString(java.util.Map)
1551       * @see org.sonar.api.utils.KeyValueFormat#parseIntString(String)
1552       * @since 2.7
1553       */
1554      public static final Metric SCM_AUTHORS_BY_LINE = new Metric.Builder(SCM_AUTHORS_BY_LINE_KEY, "Authors by line", Metric.ValueType.DATA)
1555          .setDomain(DOMAIN_SCM)
1556          .create();
1557    
1558      /**
1559       * @since 2.7
1560       */
1561      public static final String SCM_REVISIONS_BY_LINE_KEY = "revisions_by_line";
1562    
1563      /**
1564       * Key-value pairs, where key - is a number of line, and value - is a revision for this line.
1565       *
1566       * @see org.sonar.api.utils.KeyValueFormat#formatIntString(java.util.Map)
1567       * @see org.sonar.api.utils.KeyValueFormat#parseIntString(String)
1568       * @since 2.7
1569       */
1570      public static final Metric SCM_REVISIONS_BY_LINE = new Metric.Builder(SCM_REVISIONS_BY_LINE_KEY, "Revisions by line", Metric.ValueType.DATA)
1571          .setDomain(DOMAIN_SCM)
1572          .create();
1573    
1574      /**
1575       * @since 2.7
1576       */
1577      public static final String SCM_LAST_COMMIT_DATETIMES_BY_LINE_KEY = "last_commit_datetimes_by_line";
1578    
1579      /**
1580       * Key-value pairs, where key - is a number of line, and value - is a date of last commit for this line.
1581       *
1582       * @see org.sonar.api.utils.KeyValueFormat#formatIntDateTime(java.util.Map)
1583       * @see org.sonar.api.utils.KeyValueFormat#parseIntDateTime(String)
1584       * @since 2.7
1585       */
1586      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)
1587          .setDomain(DOMAIN_SCM)
1588          .create();
1589    
1590    
1591      //--------------------------------------------------------------------------------------------------------------------
1592      //
1593      // REVIEWS (since 2.14)
1594      //
1595      //--------------------------------------------------------------------------------------------------------------------
1596    
1597      /**
1598       * @since 2.14
1599       */
1600      public static final String UNREVIEWED_VIOLATIONS_KEY = "unreviewed_violations";
1601    
1602      /**
1603       * @since 2.14
1604       */
1605      public static final Metric UNREVIEWED_VIOLATIONS = new Metric.Builder(UNREVIEWED_VIOLATIONS_KEY, "Unreviewed violations", Metric.ValueType.INT)
1606          .setDescription("Violations that have not been reviewed yet")
1607          .setDirection(Metric.DIRECTION_WORST)
1608          .setDomain(DOMAIN_REVIEWS)
1609          .setBestValue(0.0)
1610          .setOptimizedBestValue(true)
1611          .create();
1612    
1613      /**
1614       * @since 2.14
1615       */
1616      public static final String NEW_UNREVIEWED_VIOLATIONS_KEY = "new_unreviewed_violations";
1617    
1618      /**
1619       * @since 2.14
1620       */
1621      public static final Metric NEW_UNREVIEWED_VIOLATIONS = new Metric.Builder(NEW_UNREVIEWED_VIOLATIONS_KEY, "New unreviewed violations", Metric.ValueType.INT)
1622          .setDescription("New violations that have not been reviewed yet")
1623          .setDirection(Metric.DIRECTION_WORST)
1624          .setQualitative(true)
1625          .setDomain(DOMAIN_REVIEWS)
1626          .setBestValue(0.0)
1627          .setOptimizedBestValue(true)
1628          .setDeleteHistoricalData(true)
1629          .create();
1630    
1631      /**
1632       * @since 2.14
1633       */
1634      public static final String FALSE_POSITIVE_REVIEWS_KEY = "false_positive_reviews";
1635    
1636      /**
1637       * @since 2.14
1638       */
1639      public static final Metric FALSE_POSITIVE_REVIEWS = new Metric.Builder(FALSE_POSITIVE_REVIEWS_KEY, "False-positive reviews", Metric.ValueType.INT)
1640          .setDescription("Active false-positive reviews")
1641          .setDirection(Metric.DIRECTION_WORST)
1642          .setDomain(DOMAIN_REVIEWS)
1643          .setBestValue(0.0)
1644          .setOptimizedBestValue(true)
1645          .create();
1646    
1647      /**
1648       * @since 2.14
1649       */
1650      public static final String ACTIVE_REVIEWS_KEY = "active_reviews";
1651    
1652      /**
1653       * @since 2.14
1654       */
1655      public static final Metric ACTIVE_REVIEWS = new Metric.Builder(ACTIVE_REVIEWS_KEY, "Active reviews", Metric.ValueType.INT)
1656          .setDescription("Active open and reopened reviews")
1657          .setDirection(Metric.DIRECTION_WORST)
1658          .setDomain(DOMAIN_REVIEWS)
1659          .setBestValue(0.0)
1660          .setOptimizedBestValue(true)
1661          .create();
1662    
1663      /**
1664       * @since 2.14
1665       */
1666      public static final String UNASSIGNED_REVIEWS_KEY = "unassigned_reviews";
1667    
1668      /**
1669       * @since 2.14
1670       */
1671      public static final Metric UNASSIGNED_REVIEWS = new Metric.Builder(UNASSIGNED_REVIEWS_KEY, "Unassigned reviews", Metric.ValueType.INT)
1672          .setDescription("Active unassigned reviews")
1673          .setDirection(Metric.DIRECTION_WORST)
1674          .setDomain(DOMAIN_REVIEWS)
1675          .setBestValue(0.0)
1676          .setOptimizedBestValue(true)
1677          .create();
1678    
1679      /**
1680       * @since 2.14
1681       */
1682      public static final String UNPLANNED_REVIEWS_KEY = "unplanned_reviews";
1683    
1684      /**
1685       * @since 2.14
1686       */
1687      public static final Metric UNPLANNED_REVIEWS = new Metric.Builder(UNPLANNED_REVIEWS_KEY, "Unplanned reviews", Metric.ValueType.INT)
1688          .setDescription("Active unplanned reviews")
1689          .setDirection(Metric.DIRECTION_WORST)
1690          .setDomain(DOMAIN_REVIEWS)
1691          .setBestValue(0.0)
1692          .setOptimizedBestValue(true)
1693          .create();
1694    
1695      // --------------------------------------------------------------------------------------------------------------------
1696      //
1697      // FILE DATA
1698      //
1699      // --------------------------------------------------------------------------------------------------------------------
1700    
1701      /**
1702       * @since 2.14
1703       */
1704      @Beta
1705      public static final String NCLOC_DATA_KEY = "ncloc_data";
1706    
1707      /**
1708       * Information about lines of code in file.
1709       * Key-value pairs, where key - is a number of line, and value - is an indicator of whether line contains code (1) or not (0).
1710       *
1711       * @see org.sonar.api.measures.FileLinesContext
1712       * @since 2.14
1713       */
1714      @Beta
1715      public static final Metric NCLOC_DATA = new Metric.Builder(NCLOC_DATA_KEY, "ncloc_data", Metric.ValueType.DATA)
1716          .setHidden(true)
1717          .setDomain(DOMAIN_SIZE)
1718          .create();
1719    
1720      /**
1721       * @since 2.14
1722       */
1723      @Beta
1724      public static final String COMMENT_LINES_DATA_KEY = "comment_lines_data";
1725    
1726      /**
1727       * Information about comments in file.
1728       * Key-value pairs, where key - is a number of line, and value - is an indicator of whether line contains comment (1) or not (0).
1729       *
1730       * @see org.sonar.api.measures.FileLinesContext
1731       * @since 2.14
1732       */
1733      @Beta
1734      public static final Metric COMMENT_LINES_DATA = new Metric.Builder(COMMENT_LINES_DATA_KEY, "comment_lines_data", Metric.ValueType.DATA)
1735          .setHidden(true)
1736          .setDomain(DOMAIN_DOCUMENTATION)
1737          .create();
1738    
1739      //--------------------------------------------------------------------------------------------------------------------
1740      //
1741      // OTHERS
1742      //
1743      //--------------------------------------------------------------------------------------------------------------------
1744    
1745      public static final String ALERT_STATUS_KEY = "alert_status";
1746      public static final Metric ALERT_STATUS = new Metric.Builder(ALERT_STATUS_KEY, "Alert", Metric.ValueType.LEVEL)
1747          .setDescription("Alert")
1748          .setDirection(Metric.DIRECTION_BETTER)
1749          .setQualitative(true)
1750          .setDomain(DOMAIN_GENERAL)
1751          .create();
1752    
1753    
1754      public static final String PROFILE_KEY = "profile";
1755      public static final Metric PROFILE = new Metric.Builder(PROFILE_KEY, "Profile", Metric.ValueType.DATA)
1756          .setDescription("Selected quality profile")
1757          .setDomain(DOMAIN_GENERAL)
1758          .create();
1759    
1760      /**
1761       * @since 2.9
1762       */
1763      public static final String PROFILE_VERSION_KEY = "profile_version";
1764    
1765      /**
1766       * @since 2.9
1767       */
1768      public static final Metric PROFILE_VERSION = new Metric.Builder(PROFILE_VERSION_KEY, "Profile version", Metric.ValueType.INT)
1769          .setDescription("Selected quality profile version")
1770          .setQualitative(false)
1771          .setDomain(DOMAIN_GENERAL)
1772          .create();
1773    
1774      private static final List<Metric> METRICS;
1775    
1776      static {
1777        METRICS = Lists.newLinkedList();
1778        for (Field field : CoreMetrics.class.getFields()) {
1779          if (Metric.class.isAssignableFrom(field.getType())) {
1780            try {
1781              Metric metric = (Metric) field.get(null);
1782              if (!StringUtils.equals(metric.getDomain(), DOMAIN_RULE_CATEGORIES)) {
1783                METRICS.add(metric);
1784              }
1785            } catch (IllegalAccessException e) {
1786              throw new SonarException("can not introspect " + CoreMetrics.class + " to get metrics", e);
1787            }
1788          }
1789        }
1790      }
1791    
1792      public static List<Metric> getMetrics() {
1793        return METRICS;
1794      }
1795    }