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 */ 020package org.sonar.plugins.design.batch; 021 022import org.sonar.api.batch.Decorator; 023import org.sonar.api.batch.DecoratorContext; 024import org.sonar.api.batch.DependedUpon; 025import org.sonar.api.measures.CoreMetrics; 026import org.sonar.api.measures.Measure; 027import org.sonar.api.measures.MeasureUtils; 028import org.sonar.api.measures.Metric; 029import org.sonar.api.resources.Project; 030import org.sonar.api.resources.Resource; 031import org.sonar.api.resources.ResourceUtils; 032import org.sonar.api.resources.Scopes; 033 034import java.util.Collection; 035import java.util.List; 036 037public 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}