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    }