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