diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2011-01-24 19:06:38 +0100 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2011-01-24 19:25:01 +0100 |
commit | 878cec92f8e39fd46628a83bba970293129de710 (patch) | |
tree | 8234845025634f6e8d589fc1ef5df79f4bb4fe12 /plugins/sonar-squid-java-plugin/src | |
parent | eb9462d6002daf7f01f8fe627b4517c065bdb5af (diff) | |
download | sonarqube-878cec92f8e39fd46628a83bba970293129de710.tar.gz sonarqube-878cec92f8e39fd46628a83bba970293129de710.zip |
SONAR-791 When the source directory is not exactly the java package root, Sonar should stop the analysis
Diffstat (limited to 'plugins/sonar-squid-java-plugin/src')
5 files changed, 160 insertions, 33 deletions
diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/JavaSourceImporter.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/JavaSourceImporter.java new file mode 100644 index 00000000000..87e7699ba88 --- /dev/null +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/JavaSourceImporter.java @@ -0,0 +1,48 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.squid; + +import org.sonar.api.batch.*; +import org.sonar.api.resources.Java; +import org.sonar.api.resources.JavaFile; +import org.sonar.api.resources.Resource; +import org.sonar.java.api.JavaUtils; + +import java.io.File; +import java.util.List; + +@DependsUpon(classes=SquidSensor.class) +@DependedUpon(JavaUtils.BARRIER_AFTER_SQUID) +public class JavaSourceImporter extends AbstractSourceImporter { + + public JavaSourceImporter() { + super(Java.INSTANCE); + } + + @Override + protected Resource createResource(File file, List<File> sourceDirs, boolean unitTest) { + return file != null ? JavaFile.fromIOFile(file, sourceDirs, unitTest) : null; + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidPlugin.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidPlugin.java index 16ba011d56d..856c3438fea 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidPlugin.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidPlugin.java @@ -24,25 +24,25 @@ import org.sonar.api.Plugin; import org.sonar.api.Properties; import org.sonar.api.Property; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -@Properties( { +@Properties({ @Property(key = SquidPluginProperties.SQUID_ANALYSE_ACCESSORS_PROPERTY, - defaultValue = SquidPluginProperties.SQUID_ANALYSE_ACCESSORS_DEFAULT_VALUE - + "", - name = "Separate accessors", - description = "Flag whether Squid should separate accessors (getters/setters) from methods. " + - "In that case, accessors are not counted in metrics such as complexity or API documentation.", - project = true, global = true), + defaultValue = SquidPluginProperties.SQUID_ANALYSE_ACCESSORS_DEFAULT_VALUE + + "", + name = "Separate accessors", + description = "Flag whether Squid should separate accessors (getters/setters) from methods. " + + "In that case, accessors are not counted in metrics such as complexity or API documentation.", + project = true, global = true), @Property(key = SquidPluginProperties.FIELDS_TO_EXCLUDE_FROM_LCOM4_COMPUTATION, - defaultValue = SquidPluginProperties.FIELDS_TO_EXCLUDE_FROM_LCOM4_COMPUTATION_DEFAULT_VALUE, - name = "List of fields to exclude from LCOM4 computation", - description = "Some fields should not be taken into account when computing LCOM4 measure as they " + - "unexpectedly and artificially decrease the LCOM4 measure. " - + "The best example is a logger used by all methods of a class. " + - "All field names to exclude from LCOM4 computation must be separated by a comma.", - project = true, global = true) }) + defaultValue = SquidPluginProperties.FIELDS_TO_EXCLUDE_FROM_LCOM4_COMPUTATION_DEFAULT_VALUE, + name = "List of fields to exclude from LCOM4 computation", + description = "Some fields should not be taken into account when computing LCOM4 measure as they " + + "unexpectedly and artificially decrease the LCOM4 measure. " + + "The best example is a logger used by all methods of a class. " + + "All field names to exclude from LCOM4 computation must be separated by a comma.", + project = true, global = true)}) public class SquidPlugin implements Plugin { public String getKey() { @@ -58,13 +58,7 @@ public class SquidPlugin implements Plugin { } public List getExtensions() { - List list = new ArrayList(); - - list.add(SquidSearchProxy.class); - list.add(SquidSensor.class); - list.add(SquidRuleRepository.class); - - return list; + return Arrays.asList(SquidSearchProxy.class, SquidSensor.class, SquidRuleRepository.class, JavaSourceImporter.class); } @Override diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java index 5abb4f50b67..c1b242e09de 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java @@ -26,7 +26,9 @@ import org.sonar.api.checks.AnnotationCheckFactory; import org.sonar.api.checks.NoSonarFilter; import org.sonar.api.profiles.RulesProfile; import org.sonar.api.resources.Java; +import org.sonar.api.resources.JavaFile; import org.sonar.api.resources.Project; +import org.sonar.java.api.JavaUtils; import java.io.File; import java.nio.charset.Charset; @@ -34,20 +36,22 @@ import java.util.Collection; import java.util.List; @Phase(name = Phase.Name.PRE) -/* TODO is the flag still used ? */ -@DependedUpon(value = Sensor.FLAG_SQUID_ANALYSIS, classes = NoSonarFilter.class) +@DependsUpon(JavaUtils.BARRIER_BEFORE_SQUID) +@DependedUpon(value = JavaUtils.BARRIER_AFTER_SQUID, classes = NoSonarFilter.class) public class SquidSensor implements Sensor { private SquidSearchProxy proxy; private NoSonarFilter noSonarFilter; private RulesProfile profile; private ProjectClasspath projectClasspath; + private ResourceCreationLock lock; - public SquidSensor(RulesProfile profile, SquidSearchProxy proxy, NoSonarFilter noSonarFilter, ProjectClasspath projectClasspath) { + public SquidSensor(RulesProfile profile, SquidSearchProxy proxy, NoSonarFilter noSonarFilter, ProjectClasspath projectClasspath, ResourceCreationLock lock) { this.proxy = proxy; this.noSonarFilter = noSonarFilter; this.profile = profile; this.projectClasspath = projectClasspath; + this.lock = lock; } public boolean shouldExecuteOnProject(Project project) { @@ -56,6 +60,12 @@ public class SquidSensor implements Sensor { @SuppressWarnings("unchecked") public void analyse(Project project, SensorContext context) { + analyzeMainSources(project, context); + browseTestSources(project, context); + lock.lock(); + } + + private void analyzeMainSources(Project project, SensorContext context) { boolean analyzePropertyAccessors = project.getConfiguration().getBoolean(SquidPluginProperties.SQUID_ANALYSE_ACCESSORS_PROPERTY, SquidPluginProperties.SQUID_ANALYSE_ACCESSORS_DEFAULT_VALUE); String fieldNamesToExcludeFromLcom4Computation = project.getConfiguration().getString( @@ -66,16 +76,26 @@ public class SquidSensor implements Sensor { AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, SquidConstants.REPOSITORY_KEY, SquidRuleRepository.getCheckClasses()); SquidExecutor squidExecutor = new SquidExecutor(analyzePropertyAccessors, fieldNamesToExcludeFromLcom4Computation, factory, charset); - squidExecutor.scan(getSourceFiles(project), getBytecodeFiles(project)); + squidExecutor.scan(getMainSourceFiles(project), getMainBytecodeFiles(project)); squidExecutor.save(project, context, noSonarFilter); squidExecutor.initSonarProxy(proxy); } - private List<File> getSourceFiles(Project project) { + private void browseTestSources(Project project, SensorContext context) { + for (File testFile : getTestSourceFiles(project)) { + context.index(JavaFile.fromIOFile(testFile, project.getFileSystem().getTestDirs(), true)); + } + } + + private List<File> getTestSourceFiles(Project project) { + return project.getFileSystem().getTestFiles(Java.INSTANCE); + } + + private List<File> getMainSourceFiles(Project project) { return project.getFileSystem().getJavaSourceFiles(); } - private Collection<File> getBytecodeFiles(Project project) { + private Collection<File> getMainBytecodeFiles(Project project) { Collection<File> bytecodeFiles = projectClasspath.getElements(); if ( !hasProjectBytecodeFiles(project)) { File classesDir = project.getFileSystem().getBuildOutputDir(); diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/Lcom4BlocksBridge.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/Lcom4BlocksBridge.java index 14a9b1b09b7..8971e618b4e 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/Lcom4BlocksBridge.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/Lcom4BlocksBridge.java @@ -19,9 +19,11 @@ */ package org.sonar.plugins.squid.bridges; +import com.google.common.collect.Lists; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; import org.sonar.api.measures.PersistenceMode; +import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Resource; import org.sonar.java.bytecode.asm.AsmField; import org.sonar.java.bytecode.asm.AsmMethod; @@ -29,7 +31,10 @@ import org.sonar.java.bytecode.asm.AsmResource; import org.sonar.squid.api.SourceFile; import org.sonar.squid.measures.Metric; -import java.util.*; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Set; public class Lcom4BlocksBridge extends Bridge { @@ -62,7 +67,7 @@ public class Lcom4BlocksBridge extends Bridge { protected String serialize(List<Set<AsmResource>> blocks) { sortBlocks(blocks); - + StringBuilder sb = new StringBuilder(); sb.append('['); @@ -102,7 +107,7 @@ public class Lcom4BlocksBridge extends Bridge { } protected List<AsmResource> sortResourcesInBlock(Set<AsmResource> block) { - List<AsmResource> result = new ArrayList<AsmResource>(); + List<AsmResource> result = Lists.newArrayList(); result.addAll(block); Collections.sort(result, new Comparator<AsmResource>() { @@ -127,10 +132,10 @@ public class Lcom4BlocksBridge extends Bridge { private static String toQualifier(AsmResource asmResource) { if (asmResource instanceof AsmField) { - return Resource.QUALIFIER_FIELD; + return Qualifiers.FIELD; } if (asmResource instanceof AsmMethod) { - return Resource.QUALIFIER_METHOD; + return Qualifiers.METHOD; } throw new IllegalArgumentException("Wrong ASM resource: " + asmResource.getClass()); } diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/JavaSourceImporterTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/JavaSourceImporterTest.java new file mode 100644 index 00000000000..c6667a6920e --- /dev/null +++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/JavaSourceImporterTest.java @@ -0,0 +1,60 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.squid; + +import org.apache.commons.io.FileUtils; +import org.junit.Test; +import org.sonar.api.resources.JavaFile; +import org.sonar.api.resources.JavaPackage; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.ResourceUtils; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class JavaSourceImporterTest { + + @Test + public void shouldDefineMainFile() throws IOException { + JavaSourceImporter importer = new JavaSourceImporter(); + Resource clazz = importer.createResource(new File(newDir("source1"), "/MyClass.java"), Arrays.asList(newDir("source1")), false); + assertThat(clazz, is(JavaFile.class)); + assertThat(clazz.getKey(), is(JavaPackage.DEFAULT_PACKAGE_NAME + ".MyClass")); + assertThat(clazz.getName(), is("MyClass")); + } + + @Test + public void shouldDefineTestFile() throws IOException { + JavaSourceImporter importer = new JavaSourceImporter(); + Resource resource = importer.createResource(new File(newDir("tests"), "/MyClassTest.java"), Arrays.asList(newDir("tests")), true); + assertThat(resource, is(JavaFile.class)); + assertThat(ResourceUtils.isUnitTestClass(resource), is(true)); + } + + private File newDir(String relativePath) throws IOException { + File target = new File("target", relativePath); + FileUtils.forceMkdir(target); + return target; + } +}
\ No newline at end of file |