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 org.apache.commons.lang.StringUtils;
023    import org.sonar.api.resources.Scopes;
024    import org.sonar.api.utils.SonarException;
025    
026    import java.lang.reflect.Field;
027    import java.util.ArrayList;
028    import java.util.HashSet;
029    import java.util.List;
030    import java.util.Set;
031    
032    /**
033     * @since 1.10
034     */
035    public final class CoreMetrics {
036    
037      private CoreMetrics() {
038        // only static stuff
039      }
040    
041      public static final String DOMAIN_SIZE = "Size";
042      public static final String DOMAIN_TESTS = "Tests";
043      public static final String DOMAIN_COMPLEXITY = "Complexity";
044      public static final String DOMAIN_DOCUMENTATION = "Documentation";
045      public static final String DOMAIN_RULES = "Rules";
046    
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(LINES_KEY, "Lines", "Lines", Metric.ValueType.INT, Metric.DIRECTION_WORST, false,
059          DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false));
060    
061      public static final String GENERATED_LINES_KEY = "generated_lines";
062      public static final Metric GENERATED_LINES = new Metric(GENERATED_LINES_KEY, "Generated Lines", "Number of generated lines",
063          Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setBestValue(0.0).setOptimizedBestValue(true).setFormula(
064          new SumChildValuesFormula(false));
065    
066      public static final String NCLOC_KEY = "ncloc";
067      public static final Metric NCLOC = new Metric(NCLOC_KEY, "Lines of code", "Non Commenting Lines of Code", Metric.ValueType.INT,
068          Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false));
069    
070      public static final String GENERATED_NCLOC_KEY = "generated_ncloc";
071      public static final Metric GENERATED_NCLOC = new Metric(GENERATED_NCLOC_KEY, "Generated lines of code",
072          "Generated non Commenting Lines of Code", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setBestValue(0.0)
073          .setOptimizedBestValue(true).setFormula(new SumChildValuesFormula(false));
074    
075      public static final String CLASSES_KEY = "classes";
076      public static final Metric CLASSES = new Metric(CLASSES_KEY, "Classes", "Classes", Metric.ValueType.INT, Metric.DIRECTION_WORST, false,
077          DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false));
078    
079      public static final String FILES_KEY = "files";
080      public static final Metric FILES = new Metric(FILES_KEY, "Files", "Number of files", Metric.ValueType.INT, Metric.DIRECTION_WORST, false,
081          DOMAIN_SIZE);
082    
083      public static final String DIRECTORIES_KEY = "directories";
084      public static final Metric DIRECTORIES = new Metric(DIRECTORIES_KEY, "Directories", "Directories", Metric.ValueType.INT,
085          Metric.DIRECTION_WORST, false, DOMAIN_SIZE);
086    
087      public static final String PACKAGES_KEY = "packages";
088      public static final Metric PACKAGES = new Metric(PACKAGES_KEY, "Packages", "Packages", Metric.ValueType.INT, Metric.DIRECTION_WORST,
089          false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false));
090    
091      public static final String FUNCTIONS_KEY = "functions";
092      public static final Metric FUNCTIONS = new Metric(FUNCTIONS_KEY, "Methods", "Methods", Metric.ValueType.INT, Metric.DIRECTION_WORST,
093          false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false));
094    
095      public static final String ACCESSORS_KEY = "accessors";
096      public static final Metric ACCESSORS = new Metric(ACCESSORS_KEY, "Accessors", "Accessors", Metric.ValueType.INT, Metric.DIRECTION_WORST,
097          false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false));
098    
099      public static final String PARAGRAPHS_KEY = "paragraphs";
100      public static final Metric PARAGRAPHS = new Metric(PARAGRAPHS_KEY, "Paragraphs", "Number of paragraphs", Metric.ValueType.INT,
101          Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false));
102    
103      public static final String STATEMENTS_KEY = "statements";
104      public static final Metric STATEMENTS = new Metric(STATEMENTS_KEY, "Statements", "Number of statements", Metric.ValueType.INT,
105          Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false));
106    
107      public static final String PUBLIC_API_KEY = "public_api";
108      public static final Metric PUBLIC_API = new Metric(PUBLIC_API_KEY, "Public API", "Public API", Metric.ValueType.INT,
109          Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false));
110    
111      public static final String COMPLEXITY_KEY = "complexity";
112      public static final Metric COMPLEXITY = new Metric(COMPLEXITY_KEY, "Complexity", "Cyclomatic complexity", Metric.ValueType.INT,
113          Metric.DIRECTION_WORST, false, DOMAIN_COMPLEXITY).setFormula(new SumChildValuesFormula(false));
114    
115      public static final String CLASS_COMPLEXITY_KEY = "class_complexity";
116      public static final Metric CLASS_COMPLEXITY = new Metric(CLASS_COMPLEXITY_KEY, "Complexity /class", "Complexity average by class",
117          Metric.ValueType.FLOAT, Metric.DIRECTION_WORST, true, DOMAIN_COMPLEXITY)
118          .setFormula(new AverageComplexityFormula(CoreMetrics.CLASSES));
119    
120      public static final String FUNCTION_COMPLEXITY_KEY = "function_complexity";
121      public static final Metric FUNCTION_COMPLEXITY = new Metric(FUNCTION_COMPLEXITY_KEY, "Complexity /method",
122          "Complexity average by method", Metric.ValueType.FLOAT, Metric.DIRECTION_WORST, true, DOMAIN_COMPLEXITY)
123          .setFormula(new AverageComplexityFormula(CoreMetrics.FUNCTIONS));
124    
125      public static final String FILE_COMPLEXITY_KEY = "file_complexity";
126      public static final Metric FILE_COMPLEXITY = new Metric(FILE_COMPLEXITY_KEY, "Complexity /file", "Complexity average by file",
127          Metric.ValueType.FLOAT, Metric.DIRECTION_WORST, true, DOMAIN_COMPLEXITY).setFormula(new AverageComplexityFormula(CoreMetrics.FILES));
128    
129      public static final String PARAGRAPH_COMPLEXITY_KEY = "paragraph_complexity";
130      public static final Metric PARAGRAPH_COMPLEXITY = new Metric(PARAGRAPH_COMPLEXITY_KEY, "Complexity /paragraph",
131          "Complexity average by paragraph", Metric.ValueType.FLOAT, Metric.DIRECTION_WORST, true, DOMAIN_COMPLEXITY)
132          .setFormula(new AverageComplexityFormula(CoreMetrics.PARAGRAPHS));
133    
134      public static final String CLASS_COMPLEXITY_DISTRIBUTION_KEY = "class_complexity_distribution";
135      public static final Metric CLASS_COMPLEXITY_DISTRIBUTION = new Metric(CLASS_COMPLEXITY_DISTRIBUTION_KEY,
136          "Classes distribution /complexity", "Classes distribution /complexity", Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true,
137          DOMAIN_COMPLEXITY).setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY));
138    
139      public static final String FUNCTION_COMPLEXITY_DISTRIBUTION_KEY = "function_complexity_distribution";
140      public static final Metric FUNCTION_COMPLEXITY_DISTRIBUTION = new Metric(FUNCTION_COMPLEXITY_DISTRIBUTION_KEY,
141          "Functions distribution /complexity", "Functions distribution /complexity", Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true,
142          DOMAIN_COMPLEXITY).setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY));
143    
144      public static final String FILE_COMPLEXITY_DISTRIBUTION_KEY = "file_complexity_distribution";
145      public static final Metric FILE_COMPLEXITY_DISTRIBUTION = new Metric(FILE_COMPLEXITY_DISTRIBUTION_KEY, "Files distribution /complexity",
146          "Files distribution /complexity", Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true, DOMAIN_COMPLEXITY)
147          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY));
148    
149      public static final String PARAGRAPH_COMPLEXITY_DISTRIBUTION_KEY = "paragraph_complexity_distribution";
150      public static final Metric PARAGRAPH_COMPLEXITY_DISTRIBUTION = new Metric(PARAGRAPH_COMPLEXITY_DISTRIBUTION_KEY,
151          "Paragraph distribution /complexity", "Paragraph distribution /complexity", Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true,
152          DOMAIN_COMPLEXITY).setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY));
153    
154      public static final String COMMENT_LINES_KEY = "comment_lines";
155      public static final Metric COMMENT_LINES = new Metric(COMMENT_LINES_KEY, "Comment lines", "Number of comment lines",
156          Metric.ValueType.INT, Metric.DIRECTION_BETTER, false, DOMAIN_DOCUMENTATION).setFormula(new SumChildValuesFormula(false));
157    
158      public static final String COMMENT_LINES_DENSITY_KEY = "comment_lines_density";
159      public static final Metric COMMENT_LINES_DENSITY = new Metric(COMMENT_LINES_DENSITY_KEY, "Comments (%)",
160          "Comments balanced by ncloc + comment lines", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_DOCUMENTATION);
161    
162      public static final String COMMENT_BLANK_LINES_KEY = "comment_blank_lines";
163      public static final Metric COMMENT_BLANK_LINES = new Metric(COMMENT_BLANK_LINES_KEY, "Blank comments",
164          "Comments that do not contain comments", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, CoreMetrics.DOMAIN_DOCUMENTATION)
165          .setFormula(new SumChildValuesFormula(false)).setBestValue(0.0).setOptimizedBestValue(true);
166    
167      public static final String PUBLIC_DOCUMENTED_API_DENSITY_KEY = "public_documented_api_density";
168      public static final Metric PUBLIC_DOCUMENTED_API_DENSITY = new Metric(PUBLIC_DOCUMENTED_API_DENSITY_KEY, "Public documented API (%)",
169          "Public documented classes and methods balanced by ncloc", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true,
170          DOMAIN_DOCUMENTATION).setWorstValue(0.0).setBestValue(100.0).setOptimizedBestValue(true);
171    
172      public static final String PUBLIC_UNDOCUMENTED_API_KEY = "public_undocumented_api";
173      public static final Metric PUBLIC_UNDOCUMENTED_API = new Metric(PUBLIC_UNDOCUMENTED_API_KEY, "Public undocumented API",
174          "Public undocumented classes, methods and variables", Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_DOCUMENTATION)
175          .setBestValue(0.0).setDirection(Metric.DIRECTION_WORST).setOptimizedBestValue(true).setFormula(
176              new SumChildValuesFormula(false));
177    
178      public static final String COMMENTED_OUT_CODE_LINES_KEY = "commented_out_code_lines";
179      public static final Metric COMMENTED_OUT_CODE_LINES = new Metric(COMMENTED_OUT_CODE_LINES_KEY, "Commented LOCs",
180          "Commented lines of code", Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_DOCUMENTATION).setFormula(
181          new SumChildValuesFormula(false)).setBestValue(0.0).setOptimizedBestValue(true);
182    
183      /* unit tests */
184      public static final String TESTS_KEY = "tests";
185      public static final Metric TESTS = new Metric(TESTS_KEY, "Unit tests", "Number of unit tests", Metric.ValueType.INT,
186          Metric.DIRECTION_WORST, false, DOMAIN_TESTS);
187    
188      public static final String TEST_EXECUTION_TIME_KEY = "test_execution_time";
189      public static final Metric TEST_EXECUTION_TIME = new Metric(TEST_EXECUTION_TIME_KEY, "Unit tests duration",
190          "Execution duration of unit tests ", Metric.ValueType.MILLISEC, Metric.DIRECTION_WORST, false, DOMAIN_TESTS);
191    
192      public static final String TEST_ERRORS_KEY = "test_errors";
193      public static final Metric TEST_ERRORS = new Metric(TEST_ERRORS_KEY, "Unit test errors", "Number of unit test errors",
194          Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_TESTS).setBestValue(0.0).setOptimizedBestValue(true);
195      public static final String SKIPPED_TESTS_KEY = "skipped_tests";
196      public static final Metric SKIPPED_TESTS = new Metric(SKIPPED_TESTS_KEY, "Skipped unit tests", "Number of skipped unit tests",
197          Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_TESTS).setBestValue(0.0).setOptimizedBestValue(true);
198      public static final String TEST_FAILURES_KEY = "test_failures";
199      public static final Metric TEST_FAILURES = new Metric(TEST_FAILURES_KEY, "Unit test failures", "Number of unit test failures",
200          Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_TESTS).setBestValue(0.0).setOptimizedBestValue(true);
201      public static final String TEST_SUCCESS_DENSITY_KEY = "test_success_density";
202      public static final Metric TEST_SUCCESS_DENSITY = new Metric(TEST_SUCCESS_DENSITY_KEY, "Unit test success (%)",
203          "Density of successful unit tests", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_TESTS).setWorstValue(0.0)
204          .setBestValue(100.0).setOptimizedBestValue(true);
205      public static final String TEST_DATA_KEY = "test_data";
206      public static final Metric TEST_DATA = new Metric(TEST_DATA_KEY, "Unit tests details", "Unit tests details", Metric.ValueType.DATA,
207          Metric.DIRECTION_WORST, false, DOMAIN_TESTS);
208    
209      public static final String COVERAGE_KEY = "coverage";
210      public static final Metric COVERAGE = new Metric(COVERAGE_KEY, "Coverage", "Coverage by unit tests", Metric.ValueType.PERCENT,
211          Metric.DIRECTION_BETTER, true, DOMAIN_TESTS).setWorstValue(0.0).setBestValue(100.0);
212    
213      public static final String LINES_TO_COVER_KEY = "lines_to_cover";
214      public static final Metric LINES_TO_COVER = new Metric(LINES_TO_COVER_KEY, "Lines to cover", "Lines to cover", Metric.ValueType.INT,
215          Metric.DIRECTION_BETTER, false, DOMAIN_TESTS).setFormula(new SumChildValuesFormula(false)).setHidden(true);
216    
217      public static final String UNCOVERED_LINES_KEY = "uncovered_lines";
218      public static final Metric UNCOVERED_LINES = new Metric(UNCOVERED_LINES_KEY, "Uncovered lines", "Uncovered lines", Metric.ValueType.INT,
219          Metric.DIRECTION_WORST, false, DOMAIN_TESTS).setFormula(new SumChildValuesFormula(false));
220    
221      public static final String LINE_COVERAGE_KEY = "line_coverage";
222      public static final Metric LINE_COVERAGE = new Metric(LINE_COVERAGE_KEY, "Line coverage", "Line coverage", Metric.ValueType.PERCENT,
223          Metric.DIRECTION_BETTER, true, DOMAIN_TESTS);
224    
225      public static final String COVERAGE_LINE_HITS_DATA_KEY = "coverage_line_hits_data";
226      public static final Metric COVERAGE_LINE_HITS_DATA = new Metric(COVERAGE_LINE_HITS_DATA_KEY, "Coverage hits data",
227          "Code coverage line hits data", Metric.ValueType.DATA, Metric.DIRECTION_NONE, false, DOMAIN_TESTS);
228    
229      public static final String CONDITIONS_TO_COVER_KEY = "conditions_to_cover";
230      public static final Metric CONDITIONS_TO_COVER = new Metric(CONDITIONS_TO_COVER_KEY, "Conditions to cover", "Conditions to cover",
231          Metric.ValueType.INT, Metric.DIRECTION_BETTER, false, DOMAIN_TESTS).setFormula(new SumChildValuesFormula(false)).setHidden(true);
232    
233      public static final String UNCOVERED_CONDITIONS_KEY = "uncovered_conditions";
234      public static final Metric UNCOVERED_CONDITIONS = new Metric(UNCOVERED_CONDITIONS_KEY, "Uncovered conditions", "Uncovered conditions",
235          Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_TESTS).setFormula(new SumChildValuesFormula(false));
236    
237      public static final String BRANCH_COVERAGE_KEY = "branch_coverage";
238      public static final Metric BRANCH_COVERAGE = new Metric(BRANCH_COVERAGE_KEY, "Branch coverage", "Branch coverage",
239          Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_TESTS).setWorstValue(0.0).setBestValue(100.0);
240    
241      public static final String BRANCH_COVERAGE_HITS_DATA_KEY = "branch_coverage_hits_data";
242      public static final Metric BRANCH_COVERAGE_HITS_DATA = new Metric(BRANCH_COVERAGE_HITS_DATA_KEY, "Branch coverage hits",
243          "Branch coverage hits", Metric.ValueType.DATA, Metric.DIRECTION_NONE, false, DOMAIN_TESTS);
244    
245      /**
246       * @deprecated replaced since 1.11 by UNCOVERED_LINES and UNCOVERED_CONDITIONS
247       */
248      @Deprecated
249      public static final String UNCOVERED_COMPLEXITY_BY_TESTS_KEY = "uncovered_complexity_by_tests";
250      /**
251       * @deprecated replaced since 1.11 by UNCOVERED_LINES and UNCOVERED_CONDITIONS
252       */
253      @Deprecated
254      public static final Metric UNCOVERED_COMPLEXITY_BY_TESTS = new Metric(UNCOVERED_COMPLEXITY_BY_TESTS_KEY, "Uncovered complexity",
255          "Uncovered complexity", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_COMPLEXITY).setFormula(new SumChildValuesFormula(
256          false));
257    
258      public static final String DUPLICATED_LINES_KEY = "duplicated_lines";
259      public static final Metric DUPLICATED_LINES = new Metric(DUPLICATED_LINES_KEY, "Duplicated lines", "Duplicated lines",
260          Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_DUPLICATION).setBestValue(0.0).setOptimizedBestValue(true);
261    
262      public static final String DUPLICATED_BLOCKS_KEY = "duplicated_blocks";
263      public static final Metric DUPLICATED_BLOCKS = new Metric(DUPLICATED_BLOCKS_KEY, "Duplicated blocks", "Duplicated blocks",
264          Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_DUPLICATION).setBestValue(0.0).setOptimizedBestValue(true);
265    
266      public static final String DUPLICATED_FILES_KEY = "duplicated_files";
267      public static final Metric DUPLICATED_FILES = new Metric(DUPLICATED_FILES_KEY, "Duplicated files", "Duplicated files",
268          Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_DUPLICATION).setBestValue(0.0).setOptimizedBestValue(true);
269    
270      public static final String DUPLICATED_LINES_DENSITY_KEY = "duplicated_lines_density";
271      public static final Metric DUPLICATED_LINES_DENSITY = new Metric(DUPLICATED_LINES_DENSITY_KEY, "Duplicated lines (%)",
272          "Duplicated lines balanced by statements", Metric.ValueType.PERCENT, Metric.DIRECTION_WORST, true, DOMAIN_DUPLICATION).setWorstValue(
273          50.0).setBestValue(0.0).setOptimizedBestValue(true);
274    
275      public static final String DUPLICATIONS_DATA_KEY = "duplications_data";
276      public static final Metric DUPLICATIONS_DATA = new Metric(DUPLICATIONS_DATA_KEY, "Duplications details", "Duplications details",
277          Metric.ValueType.DATA, Metric.DIRECTION_NONE, false, DOMAIN_DUPLICATION);
278    
279      /* coding rules */
280      /**
281       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
282       */
283      @Deprecated
284      public static final String USABILITY_KEY = "usability";
285    
286      /**
287       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
288       */
289      @Deprecated
290      public static final Metric USABILITY = new Metric(USABILITY_KEY, "Usability", "Usability", Metric.ValueType.PERCENT,
291          Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
292    
293      /**
294       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
295       */
296      @Deprecated
297      public static final String RELIABILITY_KEY = "reliability";
298    
299      /**
300       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
301       */
302      @Deprecated
303      public static final Metric RELIABILITY = new Metric(RELIABILITY_KEY, "Reliability", "Reliability", Metric.ValueType.PERCENT,
304          Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
305    
306      /**
307       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
308       */
309      @Deprecated
310      public static final String EFFICIENCY_KEY = "efficiency";
311    
312      /**
313       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
314       */
315      @Deprecated
316      public static final Metric EFFICIENCY = new Metric(EFFICIENCY_KEY, "Efficiency", "Efficiency", Metric.ValueType.PERCENT,
317          Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
318    
319      /**
320       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
321       */
322      @Deprecated
323      public static final String PORTABILITY_KEY = "portability";
324    
325      /**
326       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
327       */
328      @Deprecated
329      public static final Metric PORTABILITY = new Metric(PORTABILITY_KEY, "Portability", "Portability", Metric.ValueType.PERCENT,
330          Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
331    
332      /**
333       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
334       */
335      @Deprecated
336      public static final String MAINTAINABILITY_KEY = "maintainability";
337    
338      /**
339       * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
340       */
341      @Deprecated
342      public static final Metric MAINTAINABILITY = new Metric(MAINTAINABILITY_KEY, "Maintainability", "Maintainability",
343          Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_RULE_CATEGORIES).setBestValue(100.0).setOptimizedBestValue(true);
344    
345      public static final String WEIGHTED_VIOLATIONS_KEY = "weighted_violations";
346      public static final Metric WEIGHTED_VIOLATIONS = new Metric(WEIGHTED_VIOLATIONS_KEY, "Weighted violations", "Weighted Violations",
347          Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setHidden(true);
348    
349      public static final String VIOLATIONS_DENSITY_KEY = "violations_density";
350      public static final Metric VIOLATIONS_DENSITY = new Metric(VIOLATIONS_DENSITY_KEY, "Rules compliance", "Rules compliance",
351          Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_RULES);
352    
353      public static final String VIOLATIONS_KEY = "violations";
354      public static final Metric VIOLATIONS = new Metric(VIOLATIONS_KEY, "Violations", "Violations", Metric.ValueType.INT,
355          Metric.DIRECTION_WORST, true, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
356    
357      public static final String BLOCKER_VIOLATIONS_KEY = "blocker_violations";
358      public static final Metric BLOCKER_VIOLATIONS = new Metric(BLOCKER_VIOLATIONS_KEY, "Blocker violations", "Blocker violations",
359          Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
360    
361      public static final String CRITICAL_VIOLATIONS_KEY = "critical_violations";
362      public static final Metric CRITICAL_VIOLATIONS = new Metric(CRITICAL_VIOLATIONS_KEY, "Critical violations", "Critical violations",
363          Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
364    
365      public static final String MAJOR_VIOLATIONS_KEY = "major_violations";
366      public static final Metric MAJOR_VIOLATIONS = new Metric(MAJOR_VIOLATIONS_KEY, "Major violations", "Major violations",
367          Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
368    
369      public static final String MINOR_VIOLATIONS_KEY = "minor_violations";
370      public static final Metric MINOR_VIOLATIONS = new Metric(MINOR_VIOLATIONS_KEY, "Minor violations", "Minor violations",
371          Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
372    
373      public static final String INFO_VIOLATIONS_KEY = "info_violations";
374      public static final Metric INFO_VIOLATIONS = new Metric(INFO_VIOLATIONS_KEY, "Info violations", "Info violations", Metric.ValueType.INT,
375          Metric.DIRECTION_WORST, true, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
376    
377      public static final String NEW_VIOLATIONS_KEY = "new_violations";
378      public static final Metric NEW_VIOLATIONS = new Metric(NEW_VIOLATIONS_KEY, "New Violations", "New Violations", Metric.ValueType.INT,
379          Metric.DIRECTION_WORST, true, DOMAIN_RULES).setHidden(true).setBestValue(0.0).setOptimizedBestValue(true);
380    
381      public static final String NEW_BLOCKER_VIOLATIONS_KEY = "new_blocker_violations";
382      public static final Metric NEW_BLOCKER_VIOLATIONS = new Metric(NEW_BLOCKER_VIOLATIONS_KEY, "New Blocker violations", "New Blocker violations",
383          Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setHidden(true).setBestValue(0.0).setOptimizedBestValue(true);
384    
385      public static final String NEW_CRITICAL_VIOLATIONS_KEY = "new_critical_violations";
386      public static final Metric NEW_CRITICAL_VIOLATIONS = new Metric(NEW_CRITICAL_VIOLATIONS_KEY, "New Critical violations", "New Critical violations",
387          Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setHidden(true).setBestValue(0.0).setOptimizedBestValue(true);
388    
389      public static final String NEW_MAJOR_VIOLATIONS_KEY = "new_major_violations";
390      public static final Metric NEW_MAJOR_VIOLATIONS = new Metric(NEW_MAJOR_VIOLATIONS_KEY, "New Major violations", "New Major violations",
391          Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setHidden(true).setBestValue(0.0).setOptimizedBestValue(true);
392    
393      public static final String NEW_MINOR_VIOLATIONS_KEY = "new_minor_violations";
394      public static final Metric NEW_MINOR_VIOLATIONS = new Metric(NEW_MINOR_VIOLATIONS_KEY, "New Minor violations", "New Minor violations",
395          Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setHidden(true).setBestValue(0.0).setOptimizedBestValue(true);
396    
397      public static final String NEW_INFO_VIOLATIONS_KEY = "new_info_violations";
398      public static final Metric NEW_INFO_VIOLATIONS = new Metric(NEW_INFO_VIOLATIONS_KEY, "New Info violations", "New Info violations",
399          Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setHidden(true).setBestValue(0.0).setOptimizedBestValue(true);
400    
401      /* Design */
402    
403      public static final String ABSTRACTNESS_KEY = "abstractness";
404      public static final Metric ABSTRACTNESS = new Metric(ABSTRACTNESS_KEY, "Abstractness", "Abstractness", Metric.ValueType.PERCENT,
405          Metric.DIRECTION_NONE, false, DOMAIN_DESIGN);
406      public static final String INSTABILITY_KEY = "instability";
407      public static final Metric INSTABILITY = new Metric(INSTABILITY_KEY, "Instability", "Instability", Metric.ValueType.PERCENT,
408          Metric.DIRECTION_NONE, false, DOMAIN_DESIGN);
409      public static final String DISTANCE_KEY = "distance";
410      public static final Metric DISTANCE = new Metric(DISTANCE_KEY, "Distance", "Distance", Metric.ValueType.FLOAT, Metric.DIRECTION_NONE,
411          false, DOMAIN_DESIGN);
412    
413      public static final String DEPTH_IN_TREE_KEY = "dit";
414      public static final Metric DEPTH_IN_TREE = new Metric(DEPTH_IN_TREE_KEY, "Depth in Tree", "Depth in Inheritance Tree",
415          Metric.ValueType.INT, Metric.DIRECTION_NONE, false, DOMAIN_DESIGN);
416    
417      public static final String NUMBER_OF_CHILDREN_KEY = "noc";
418      public static final Metric NUMBER_OF_CHILDREN = new Metric(NUMBER_OF_CHILDREN_KEY, "Number of Children", "Number of Children",
419          Metric.ValueType.INT, Metric.DIRECTION_NONE, false, DOMAIN_DESIGN);
420    
421      public static final String RFC_KEY = "rfc";
422      public static final Metric RFC = new Metric(RFC_KEY, "RFC", "Response for Class", Metric.ValueType.INT, Metric.DIRECTION_WORST, false,
423          DOMAIN_DESIGN).setFormula(new WeightedMeanAggregationFormula(CoreMetrics.FILES, false));
424    
425      public static final String RFC_DISTRIBUTION_KEY = "rfc_distribution";
426      public static final Metric RFC_DISTRIBUTION = new Metric(RFC_DISTRIBUTION_KEY, "Class distribution /RFC", "Class distribution /RFC",
427          Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true, DOMAIN_DESIGN)
428          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY));
429    
430      public static final String LCOM4_KEY = "lcom4";
431      public static final Metric LCOM4 = new Metric(LCOM4_KEY, "LCOM4", "Lack of Cohesion of Methods", Metric.ValueType.FLOAT,
432          Metric.DIRECTION_WORST, true, DOMAIN_DESIGN).setFormula(new WeightedMeanAggregationFormula(CoreMetrics.FILES, false));
433    
434      public static final String LCOM4_BLOCKS_KEY = "lcom4_blocks";
435      public static final Metric LCOM4_BLOCKS = new Metric(LCOM4_BLOCKS_KEY, "LCOM4 blocks", "LCOM4 blocks", Metric.ValueType.DATA,
436          Metric.DIRECTION_NONE, false, DOMAIN_DESIGN).setHidden(true);
437    
438      public static final String LCOM4_DISTRIBUTION_KEY = "lcom4_distribution";
439      public static final Metric LCOM4_DISTRIBUTION = new Metric(LCOM4_DISTRIBUTION_KEY, "Class distribution /LCOM4",
440          "Class distribution /LCOM4", Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true, DOMAIN_DESIGN)
441          .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY));
442    
443      public static final String SUSPECT_LCOM4_DENSITY_KEY = "suspect_lcom4_density";
444      public static final Metric SUSPECT_LCOM4_DENSITY = new Metric(SUSPECT_LCOM4_DENSITY_KEY, "Suspect LCOM4 density",
445          "Density of classes having LCOM4>1", Metric.ValueType.PERCENT, Metric.DIRECTION_WORST, true, DOMAIN_DESIGN);
446    
447      public static final String AFFERENT_COUPLINGS_KEY = "ca";
448      public static final Metric AFFERENT_COUPLINGS = new Metric(AFFERENT_COUPLINGS_KEY, "Afferent couplings", "Afferent couplings",
449          Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_DESIGN);
450      public static final String EFFERENT_COUPLINGS_KEY = "ce";
451      public static final Metric EFFERENT_COUPLINGS = new Metric(EFFERENT_COUPLINGS_KEY, "Efferent couplings", "Efferent couplings",
452          Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_DESIGN);
453    
454      public static final String DEPENDENCY_MATRIX_KEY = "dsm";
455      public static final Metric DEPENDENCY_MATRIX = new Metric(DEPENDENCY_MATRIX_KEY, "Dependency Matrix", "Dependency Matrix",
456          Metric.ValueType.DATA, Metric.DIRECTION_NONE, false, DOMAIN_DESIGN);
457    
458      public static final String PACKAGE_CYCLES_KEY = "package_cycles";
459      public static final Metric PACKAGE_CYCLES = new Metric(PACKAGE_CYCLES_KEY, "Package cycles", "Package cycles", Metric.ValueType.INT,
460          Metric.DIRECTION_WORST, true, DOMAIN_DESIGN).setFormula(new SumChildValuesFormula(false));
461    
462      public static final String PACKAGE_TANGLE_INDEX_KEY = "package_tangle_index";
463      public static final Metric PACKAGE_TANGLE_INDEX = new Metric(PACKAGE_TANGLE_INDEX_KEY, "Package tangle index", "Package tangle index",
464          Metric.ValueType.PERCENT, Metric.DIRECTION_WORST, true, DOMAIN_DESIGN);
465    
466      public static final String PACKAGE_TANGLES_KEY = "package_tangles";
467      public static final Metric PACKAGE_TANGLES = new Metric(PACKAGE_TANGLES_KEY, "File dependencies to cut", "File dependencies to cut",
468          Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_DESIGN).setFormula(new SumChildValuesFormula(false));
469    
470      public static final String PACKAGE_FEEDBACK_EDGES_KEY = "package_feedback_edges";
471      public static final Metric PACKAGE_FEEDBACK_EDGES = new Metric(PACKAGE_FEEDBACK_EDGES_KEY, "Package dependencies to cut",
472          "Package dependencies to cut", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_DESIGN)
473          .setFormula(new SumChildValuesFormula(false));
474    
475      public static final String PACKAGE_EDGES_WEIGHT_KEY = "package_edges_weight";
476      public static final Metric PACKAGE_EDGES_WEIGHT = new Metric(PACKAGE_EDGES_WEIGHT_KEY, "Package edges weight", "Package edges weight",
477          Metric.ValueType.INT, Metric.DIRECTION_BETTER, false, DOMAIN_DESIGN).setFormula(new SumChildValuesFormula(false)).setHidden(true);
478    
479      public static final String FILE_CYCLES_KEY = "file_cycles";
480      public static final Metric FILE_CYCLES = new Metric(FILE_CYCLES_KEY, "File cycles", "File cycles", Metric.ValueType.INT,
481          Metric.DIRECTION_WORST, true, DOMAIN_DESIGN).setHidden(true);
482    
483      public static final String FILE_TANGLE_INDEX_KEY = "file_tangle_index";
484      public static final Metric FILE_TANGLE_INDEX = new Metric(FILE_TANGLE_INDEX_KEY, "File tangle index", "File tangle index",
485          Metric.ValueType.PERCENT, Metric.DIRECTION_WORST, true, DOMAIN_DESIGN).setHidden(true);
486    
487      public static final String FILE_TANGLES_KEY = "file_tangles";
488      public static final Metric FILE_TANGLES = new Metric(FILE_TANGLES_KEY, "File tangles", "Files tangles", Metric.ValueType.INT,
489          Metric.DIRECTION_WORST, false, DOMAIN_DESIGN).setHidden(true);
490    
491      public static final String FILE_FEEDBACK_EDGES_KEY = "file_feedback_edges";
492      public static final Metric FILE_FEEDBACK_EDGES = new Metric(FILE_FEEDBACK_EDGES_KEY, "Suspect file dependencies",
493          "Suspect file dependencies", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_DESIGN).setHidden(true);
494    
495      public static final String FILE_EDGES_WEIGHT_KEY = "file_edges_weight";
496      public static final Metric FILE_EDGES_WEIGHT = new Metric(FILE_EDGES_WEIGHT_KEY, "File edges weight", "File edges weight",
497          Metric.ValueType.INT, Metric.DIRECTION_BETTER, false, DOMAIN_DESIGN).setHidden(true);
498    
499      /* alerts */
500      public static final String ALERT_STATUS_KEY = "alert_status";
501      public static final Metric ALERT_STATUS = new Metric(ALERT_STATUS_KEY, "Alert", "Alert", Metric.ValueType.LEVEL, Metric.DIRECTION_BETTER,
502          true, DOMAIN_GENERAL);
503    
504      /* quality profile */
505      public static final String PROFILE_KEY = "profile";
506      public static final Metric PROFILE = new Metric(PROFILE_KEY, "Profile", "Selected quality profile", Metric.ValueType.DATA,
507          Metric.DIRECTION_NONE, false, DOMAIN_GENERAL);
508    
509      public static List<Metric> metrics = new ArrayList<Metric>();
510    
511      public static Set<String> metricKeys = new HashSet<String>();
512    
513      public static List<Metric> getMetrics() {
514        if (metrics.isEmpty()) {
515          for (Field field : CoreMetrics.class.getFields()) {
516            if (Metric.class.isAssignableFrom(field.getType())) {
517              try {
518                Metric metric = (Metric) field.get(null);
519                if (!StringUtils.equals(metric.getDomain(), DOMAIN_RULE_CATEGORIES)) {
520                  metrics.add(metric);
521                }
522              } catch (IllegalAccessException e) {
523                throw new SonarException("can not load metrics from " + CoreMetrics.class.getSimpleName(), e);
524              }
525            }
526          }
527        }
528        return metrics;
529      }
530    }