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