001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2009 SonarSource SA 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 org.sonar.api.utils.SonarException; 023 024 import java.lang.reflect.Field; 025 import java.util.*; 026 027 /** 028 * @since 1.10 029 */ 030 public final class CoreMetrics { 031 032 private CoreMetrics() { 033 } 034 035 public static final String DOMAIN_SIZE = "Size"; 036 public static final String DOMAIN_TESTS = "Tests"; 037 public static final String DOMAIN_COMPLEXITY = "Complexity"; 038 public static final String DOMAIN_DOCUMENTATION = "Documentation"; 039 public static final String DOMAIN_RULES = "Rules"; 040 public static final String DOMAIN_RULE_CATEGORIES = "Rule categories"; 041 public static final String DOMAIN_GENERAL = "General"; 042 public static final String DOMAIN_DUPLICATION = "Duplication"; 043 044 /* core statistics */ 045 public static final Metric LINES = new Metric("lines", "Lines", "Lines", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false)); 046 public static final Metric NCLOC = new Metric("ncloc", "Lines of code", "Non Commenting Lines of Code", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false)); 047 public static final Metric CLASSES = new Metric("classes", "Classes", "Classes", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false)); 048 public static final Metric FILES = new Metric("files", "Files", "Number of files", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_SIZE); 049 public static final Metric DIRECTORIES = new Metric("directories", "Directories", "Directories", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_SIZE); 050 public static final Metric PACKAGES = new Metric("packages", "Packages", "Packages", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false)); 051 public static final Metric FUNCTIONS = new Metric("functions", "Methods", "Methods", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false)); 052 public static final Metric ACCESSORS = new Metric("accessors", "Accessors", "Accessors", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false)); 053 public static final Metric STATEMENTS = new Metric("statements", "Statements", "Number of statements", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false)); 054 public static final Metric PUBLIC_API = new Metric("public_api", "Public API", "Public API", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false)); 055 056 /* complexity */ 057 public static final Metric COMPLEXITY = new Metric("complexity", "Complexity", "Cyclomatic complexity", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_COMPLEXITY).setFormula(new SumChildValuesFormula(false)); 058 public static final Metric CLASS_COMPLEXITY = new Metric("class_complexity", "Complexity /class", "Complexity average by class", Metric.ValueType.FLOAT, Metric.DIRECTION_WORST, true, DOMAIN_COMPLEXITY); 059 public static final Metric FUNCTION_COMPLEXITY = new Metric("function_complexity", "Complexity /method", "Complexity average by method", Metric.ValueType.FLOAT, Metric.DIRECTION_WORST, true, DOMAIN_COMPLEXITY); 060 public static final Metric FILE_COMPLEXITY = new Metric("file_complexity", "Complexity /file", "Complexity average by file", Metric.ValueType.FLOAT, Metric.DIRECTION_WORST, true, DOMAIN_COMPLEXITY); 061 public static final Metric CLASS_COMPLEXITY_DISTRIBUTION = new Metric("class_complexity_distribution", "Classes distribution /complexity", "Classes distribution /complexity", Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true, DOMAIN_COMPLEXITY); 062 public static final Metric FUNCTION_COMPLEXITY_DISTRIBUTION = new Metric("function_complexity_distribution", "Functions distribution /complexity", "Functions distribution /complexity", Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true, DOMAIN_COMPLEXITY); 063 064 /* comments */ 065 public static final Metric COMMENT_LINES = new Metric("comment_lines", "Comment lines", "Number of comment lines", Metric.ValueType.INT, Metric.DIRECTION_BETTER, false, DOMAIN_DOCUMENTATION).setFormula(new SumChildValuesFormula(false)); 066 public static final Metric COMMENT_LINES_DENSITY = new Metric("comment_lines_density", "Comments (%)", "Comments balanced by ncloc + comment lines", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_DOCUMENTATION); 067 public static final Metric PUBLIC_DOCUMENTED_API_DENSITY = new Metric("public_documented_api_density", "Public documented API (%)", "Public documented classes and methods balanced by ncloc", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_DOCUMENTATION) 068 .setWorstValue(0.0) 069 .setBestValue(100.0) 070 .setOptimizedBestValue(true); 071 public static final Metric PUBLIC_UNDOCUMENTED_API = new Metric("public_undocumented_api", "Public undocumented API", "Public undocumented classes, methods and variables", Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_DOCUMENTATION) 072 .setWorstValue(100.0) 073 .setBestValue(0.0) 074 .setDirection(Metric.DIRECTION_WORST) 075 .setFormula(new SumChildValuesFormula(false)); 076 public static final Metric COMMENTED_OUT_CODE_LINES = new Metric("commented_out_code_lines", "Commented LOCs", "Commented lines of code", Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_DOCUMENTATION) 077 .setFormula(new SumChildValuesFormula(false)) 078 .setBestValue(0.0) 079 .setOptimizedBestValue(true); 080 081 /* unit tests */ 082 public static final Metric TESTS = new Metric("tests", "Unit tests", "Number of unit tests", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_TESTS); 083 public static final Metric TEST_EXECUTION_TIME = new Metric("test_execution_time", "Unit tests duration", "Execution duration of unit tests ", Metric.ValueType.MILLISEC, Metric.DIRECTION_WORST, false, DOMAIN_TESTS); 084 public static final Metric TEST_ERRORS = new Metric("test_errors", "Unit test errors", "Number of unit test errors", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_TESTS) 085 .setBestValue(0.0) 086 .setOptimizedBestValue(true); 087 public static final Metric SKIPPED_TESTS = new Metric("skipped_tests", "Skipped unit tests", "Number of skipped unit tests", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_TESTS) 088 .setBestValue(0.0) 089 .setOptimizedBestValue(true); 090 public static final Metric TEST_FAILURES = new Metric("test_failures", "Unit test failures", "Number of unit test failures", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_TESTS) 091 .setBestValue(0.0) 092 .setOptimizedBestValue(true); 093 public static final Metric TEST_SUCCESS_DENSITY = new Metric("test_success_density", "Unit test success (%)", "Ratio of successful unit tests", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_TESTS) 094 .setWorstValue(0.0) 095 .setBestValue(100.0) 096 .setOptimizedBestValue(true); 097 public static final Metric TEST_DATA = new Metric("test_data", "Unit tests details", "Unit tests details", Metric.ValueType.DATA, Metric.DIRECTION_WORST, false, DOMAIN_TESTS); 098 099 100 /* code coverage by unit tests */ 101 public static final Metric COVERAGE = new Metric("coverage", "Coverage", "Coverage by unit tests", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_TESTS) 102 .setWorstValue(0.0) 103 .setBestValue(100.0); 104 105 public static final Metric LINES_TO_COVER = new Metric("lines_to_cover", "Lines to cover", "Lines to cover", Metric.ValueType.INT, Metric.DIRECTION_BETTER, false, DOMAIN_TESTS).setFormula(new SumChildValuesFormula(false)); 106 public static final Metric UNCOVERED_LINES = new Metric("uncovered_lines", "Uncovered lines", "Uncovered lines", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_TESTS).setFormula(new SumChildValuesFormula(false)); 107 public static final Metric LINE_COVERAGE = new Metric("line_coverage", "Line coverage", "Line coverage", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_TESTS); 108 public static final Metric COVERAGE_LINE_HITS_DATA = new Metric("coverage_line_hits_data", "Coverage hits data", "Code coverage line hits data", Metric.ValueType.DATA, Metric.DIRECTION_NONE, false, DOMAIN_TESTS); 109 110 public static final Metric CONDITIONS_TO_COVER = new Metric("conditions_to_cover", "Conditions to cover", "Conditions to cover", Metric.ValueType.INT, Metric.DIRECTION_BETTER, false, DOMAIN_TESTS).setFormula(new SumChildValuesFormula(false)); 111 public static final Metric UNCOVERED_CONDITIONS = new Metric("uncovered_conditions", "Uncovered conditions", "Uncovered conditions", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_TESTS).setFormula(new SumChildValuesFormula(false)); 112 public static final Metric BRANCH_COVERAGE = new Metric("branch_coverage", "Branch coverage", "Branch coverage", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_TESTS) 113 .setWorstValue(0.0) 114 .setBestValue(100.0); 115 public static final Metric BRANCH_COVERAGE_HITS_DATA = new Metric("branch_coverage_hits_data", "Branch coverage hits", "Branch coverage hits", Metric.ValueType.DATA, Metric.DIRECTION_NONE, false, DOMAIN_TESTS); 116 117 /** 118 * @deprecated replaced since 1.11 by UNCOVERED_LINES and UNCOVERED_CONDITIONS 119 */ 120 @Deprecated 121 public static final Metric UNCOVERED_COMPLEXITY_BY_TESTS = new Metric("uncovered_complexity_by_tests", "Uncovered complexity", "Uncovered complexity", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_COMPLEXITY).setFormula(new SumChildValuesFormula(false)); 122 123 124 /* duplicated lines */ 125 public static final Metric DUPLICATED_LINES = new Metric("duplicated_lines", "Duplicated lines", "Duplicated lines", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_DUPLICATION) 126 .setBestValue(0.0) 127 .setOptimizedBestValue(true); 128 public static final Metric DUPLICATED_BLOCKS = new Metric("duplicated_blocks", "Duplicated blocks", "Duplicated blocks", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_DUPLICATION) 129 .setBestValue(0.0) 130 .setOptimizedBestValue(true); 131 public static final Metric DUPLICATED_FILES = new Metric("duplicated_files", "Duplicated files", "Duplicated files", Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_DUPLICATION) 132 .setBestValue(0.0) 133 .setOptimizedBestValue(true); 134 public static final Metric DUPLICATED_LINES_DENSITY = new Metric("duplicated_lines_density", "Duplicated lines (%)", "Duplicated lines balanced by statements", Metric.ValueType.PERCENT, Metric.DIRECTION_WORST, true, DOMAIN_DUPLICATION) 135 .setWorstValue(50.0) 136 .setBestValue(0.0) 137 .setOptimizedBestValue(true); 138 139 public static final Metric DUPLICATIONS_DATA = new Metric("duplications_data", "Duplications details", "Duplications details", Metric.ValueType.DATA, Metric.DIRECTION_NONE, false, DOMAIN_DUPLICATION); 140 141 /* coding rules */ 142 public static final Metric USABILITY = new Metric("usability", "Usability", "Usability", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES) 143 .setBestValue(100.0) 144 .setOptimizedBestValue(true); 145 public static final Metric RELIABILITY = new Metric("reliability", "Reliability", "Reliability", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES) 146 .setBestValue(100.0) 147 .setOptimizedBestValue(true); 148 public static final Metric EFFICIENCY = new Metric("efficiency", "Efficiency", "Efficiency", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES) 149 .setBestValue(100.0) 150 .setOptimizedBestValue(true); 151 public static final Metric PORTABILITY = new Metric("portability", "Portability", "Portability", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES) 152 .setBestValue(100.0) 153 .setOptimizedBestValue(true); 154 public static final Metric MAINTAINABILITY = new Metric("maintainability", "Maintainability", "Maintainability", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES) 155 .setBestValue(100.0) 156 .setOptimizedBestValue(true); 157 158 public static final Metric WEIGHTED_VIOLATIONS = new Metric("weighted_violations", "Weighted violations", "Weighted Violations", Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES); 159 public static final Metric VIOLATIONS_DENSITY = new Metric("violations_density", "Rules compliance", "Rules compliance", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_RULES); 160 161 public static final Metric VIOLATIONS = new Metric("violations", "Violations", "Violations", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_RULES) 162 .setBestValue(0.0) 163 .setOptimizedBestValue(true); 164 public static final Metric BLOCKER_VIOLATIONS = new Metric("blocker_violations", "Blocker violations", "Blocker violations", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_RULES) 165 .setBestValue(0.0) 166 .setOptimizedBestValue(true); 167 public static final Metric CRITICAL_VIOLATIONS = new Metric("critical_violations", "Critical violations", "Critical violations", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_RULES) 168 .setBestValue(0.0) 169 .setOptimizedBestValue(true);; 170 public static final Metric MAJOR_VIOLATIONS = new Metric("major_violations", "Major violations", "Major violations", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_RULES) 171 .setBestValue(0.0) 172 .setOptimizedBestValue(true); 173 public static final Metric MINOR_VIOLATIONS = new Metric("minor_violations", "Minor violations", "Minor violations", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_RULES) 174 .setBestValue(0.0) 175 .setOptimizedBestValue(true); 176 public static final Metric INFO_VIOLATIONS = new Metric("info_violations", "Info violations", "Info violations", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_RULES) 177 .setBestValue(0.0) 178 .setOptimizedBestValue(true); 179 180 /* alerts */ 181 public static final Metric ALERT_STATUS = new Metric("alert_status", "Alert", "Alert", Metric.ValueType.LEVEL, Metric.DIRECTION_BETTER, true, DOMAIN_GENERAL); 182 183 /* quality profile */ 184 public static final Metric PROFILE = new Metric("profile", "Profile", "Selected quality profile", Metric.ValueType.DATA, Metric.DIRECTION_NONE, false, DOMAIN_GENERAL); 185 186 private static List<Metric> metrics = new ArrayList<Metric>(); 187 188 private static Set<String> metricKeys = new HashSet<String>(); 189 190 public static final Map<String, String> DEPRECATED_KEY = new HashMap<String, String>(); 191 192 static { 193 DEPRECATED_KEY.put("ncss", NCLOC.getKey()); 194 DEPRECATED_KEY.put("lines", LINES.getKey()); 195 DEPRECATED_KEY.put("classes_count", CLASSES.getKey()); 196 DEPRECATED_KEY.put("packages_count", PACKAGES.getKey()); 197 DEPRECATED_KEY.put("functions_count", FUNCTIONS.getKey()); 198 DEPRECATED_KEY.put("files_count", FILES.getKey()); 199 DEPRECATED_KEY.put("directories_count", DIRECTORIES.getKey()); 200 DEPRECATED_KEY.put("ccn", COMPLEXITY.getKey()); 201 DEPRECATED_KEY.put("ccn_class", CLASS_COMPLEXITY.getKey()); 202 DEPRECATED_KEY.put("ccn_file", FILE_COMPLEXITY.getKey()); 203 DEPRECATED_KEY.put("ccn_function", FUNCTION_COMPLEXITY.getKey()); 204 DEPRECATED_KEY.put("ccn_classes_count_distribution", CLASS_COMPLEXITY_DISTRIBUTION.getKey()); 205 DEPRECATED_KEY.put("comment_ratio", COMMENT_LINES_DENSITY.getKey()); 206 DEPRECATED_KEY.put("test_count", TESTS.getKey()); 207 DEPRECATED_KEY.put("test_errors_count", TEST_ERRORS.getKey()); 208 DEPRECATED_KEY.put("test_skipped_count", SKIPPED_TESTS.getKey()); 209 DEPRECATED_KEY.put("test_failures_count", TEST_FAILURES.getKey()); 210 DEPRECATED_KEY.put("test_success_percentage", TEST_SUCCESS_DENSITY.getKey()); 211 DEPRECATED_KEY.put("test_details", TEST_DATA.getKey()); 212 DEPRECATED_KEY.put("code_coverage", COVERAGE.getKey()); 213 DEPRECATED_KEY.put("code_coverage_line_hits_data", COVERAGE_LINE_HITS_DATA.getKey()); 214 DEPRECATED_KEY.put("duplicated_lines", DUPLICATED_LINES.getKey()); 215 DEPRECATED_KEY.put("duplicated_blocks", DUPLICATED_BLOCKS.getKey()); 216 DEPRECATED_KEY.put("duplicated_files", DUPLICATED_FILES.getKey()); 217 DEPRECATED_KEY.put("duplicated_lines_ratio", DUPLICATED_LINES_DENSITY.getKey()); 218 DEPRECATED_KEY.put("duplications_data", DUPLICATIONS_DATA.getKey()); 219 DEPRECATED_KEY.put("rules_compliance", VIOLATIONS_DENSITY.getKey()); 220 DEPRECATED_KEY.put("rules_violations", VIOLATIONS.getKey()); 221 DEPRECATED_KEY.put("rules_index", VIOLATIONS_DENSITY.getKey()); 222 DEPRECATED_KEY.put("rules_violations_count", VIOLATIONS.getKey()); 223 DEPRECATED_KEY.put("alert_status", ALERT_STATUS.getKey()); 224 225 } 226 227 228 public static List<Metric> getMetrics() { 229 if (metrics.isEmpty()) { 230 for (Field field : CoreMetrics.class.getFields()) { 231 if (Metric.class.isAssignableFrom(field.getType())) { 232 try { 233 metrics.add((Metric) field.get(null)); 234 } catch (IllegalAccessException e) { 235 throw new SonarException("can not load metrics from " + CoreMetrics.class.getSimpleName(), e); 236 } 237 } 238 } 239 } 240 return metrics; 241 } 242 243 public static Set<String> getKeys() { 244 if (metricKeys.isEmpty()) { 245 for (Metric metric : getMetrics()) { 246 metricKeys.add(metric.getKey()); 247 } 248 } 249 return metricKeys; 250 } 251 252 public static String toValidKey(String key) { 253 String value = DEPRECATED_KEY.get(key); 254 if (value == null) { 255 value = key; 256 } 257 return value; 258 } 259 }