001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2008-2012 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.plugins.design.batch;
021
022 import org.sonar.api.batch.Decorator;
023 import org.sonar.api.batch.DecoratorContext;
024 import org.sonar.api.batch.DependedUpon;
025 import org.sonar.api.measures.CoreMetrics;
026 import org.sonar.api.measures.Measure;
027 import org.sonar.api.measures.MeasureUtils;
028 import org.sonar.api.measures.Metric;
029 import org.sonar.api.resources.Project;
030 import org.sonar.api.resources.Resource;
031 import org.sonar.api.resources.ResourceUtils;
032 import org.sonar.api.resources.Scopes;
033
034 import java.util.Collection;
035 import java.util.List;
036
037 public class SuspectLcom4DensityDecorator implements Decorator {
038
039 public boolean shouldExecuteOnProject(Project project) {
040 return true;
041 }
042
043 @DependedUpon
044 public final Metric generatesMetric() {
045 return CoreMetrics.SUSPECT_LCOM4_DENSITY;
046 }
047
048 public void decorate(Resource resource, DecoratorContext context) {
049 if (ResourceUtils.isFile(resource)) {
050 // do nothing
051 } else if (Scopes.isDirectory(resource)) {
052 decorateDirectory(context);
053
054 } else if (Scopes.isProject(resource)) {
055 decorateProject(context);
056 }
057 }
058
059 private void decorateProject(DecoratorContext context) {
060 double total = 0.0;
061 int totalFiles = 0;
062
063 List<DecoratorContext> children = context.getChildren();
064 boolean hasLcom4=false;
065 for (DecoratorContext child : children) {
066 int files = MeasureUtils.getValue(child.getMeasure(CoreMetrics.FILES), 0.0).intValue();
067 totalFiles += files;
068 Measure childSuspectDensity = child.getMeasure(CoreMetrics.SUSPECT_LCOM4_DENSITY);
069 if (childSuspectDensity!=null && childSuspectDensity.getValue()!=null) {
070 hasLcom4=true;
071 total += childSuspectDensity.getValue() * files;
072 }
073 }
074
075 if (hasLcom4 && totalFiles > 0) {
076 context.saveMeasure(CoreMetrics.SUSPECT_LCOM4_DENSITY, (total / totalFiles));
077 }
078 }
079
080 private void decorateDirectory(DecoratorContext context) {
081 Collection<Measure> fileLcoms = context.getChildrenMeasures(CoreMetrics.LCOM4);
082 double files = MeasureUtils.getValue(context.getMeasure(CoreMetrics.FILES), 0.0);
083 if (!fileLcoms.isEmpty() && files>0.0) {
084 double suspectFiles = 0.0;
085
086 // directory children are files
087 for (Measure fileLcom : fileLcoms) {
088 if (MeasureUtils.getValue(fileLcom, 0.0) > 1.0) {
089 suspectFiles++;
090 }
091 }
092 double density = (suspectFiles / files) * 100.0;
093 context.saveMeasure(CoreMetrics.SUSPECT_LCOM4_DENSITY, density);
094 }
095 }
096 }