aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsimonbrandhof <simon.brandhof@gmail.com>2011-01-24 19:06:38 +0100
committersimonbrandhof <simon.brandhof@gmail.com>2011-01-24 19:25:01 +0100
commit878cec92f8e39fd46628a83bba970293129de710 (patch)
tree8234845025634f6e8d589fc1ef5df79f4bb4fe12
parenteb9462d6002daf7f01f8fe627b4517c065bdb5af (diff)
downloadsonarqube-878cec92f8e39fd46628a83bba970293129de710.tar.gz
sonarqube-878cec92f8e39fd46628a83bba970293129de710.zip
SONAR-791 When the source directory is not exactly the java package root, Sonar should stop the analysis
-rw-r--r--plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/testdetailsviewer/TestsViewerDefinition.java6
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java1
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java3
-rw-r--r--plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/JavaSourceImporter.java (renamed from plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/JavaSourceImporter.java)21
-rw-r--r--plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidPlugin.java38
-rw-r--r--plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java32
-rw-r--r--plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/Lcom4BlocksBridge.java15
-rw-r--r--plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/JavaSourceImporterTest.java (renamed from plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/JavaSourceImporterTest.java)27
-rw-r--r--plugins/sonar-surefire-plugin/src/test/java/org/sonar/plugins/surefire/SurefireSensorTest.java49
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/DefaultResourceCreationLock.java16
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java12
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java40
-rw-r--r--sonar-java-api/src/main/java/org/sonar/java/api/JavaClass.java11
-rw-r--r--sonar-java-api/src/main/java/org/sonar/java/api/JavaMethod.java12
-rw-r--r--sonar-java-api/src/main/java/org/sonar/java/api/JavaUtils.java11
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java9
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java12
-rw-r--r--sonar-server/src/main/java/org/sonar/server/filters/Filter.java3
-rw-r--r--tests/integration/tests/build.xml2
20 files changed, 202 insertions, 124 deletions
diff --git a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/testdetailsviewer/TestsViewerDefinition.java b/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/testdetailsviewer/TestsViewerDefinition.java
index 0cca72a7d7b..98bc53a0437 100644
--- a/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/testdetailsviewer/TestsViewerDefinition.java
+++ b/plugins/sonar-core-gwt/src/main/java/org/sonar/plugins/core/testdetailsviewer/TestsViewerDefinition.java
@@ -20,13 +20,13 @@
package org.sonar.plugins.core.testdetailsviewer;
import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.Qualifiers;
import org.sonar.api.web.*;
import org.sonar.plugins.core.testdetailsviewer.client.TestsViewer;
-@ResourceQualifier(Resource.QUALIFIER_UNIT_TEST_CLASS)
+@ResourceQualifier(Qualifiers.UNIT_TEST_FILE)
@NavigationSection(NavigationSection.RESOURCE_TAB)
-@DefaultTab(metrics={CoreMetrics.TESTS_KEY, CoreMetrics.TEST_EXECUTION_TIME_KEY, CoreMetrics.TEST_SUCCESS_DENSITY_KEY, CoreMetrics.TEST_FAILURES_KEY, CoreMetrics.TEST_ERRORS_KEY, CoreMetrics.SKIPPED_TESTS_KEY})
+@DefaultTab(metrics = {CoreMetrics.TESTS_KEY, CoreMetrics.TEST_EXECUTION_TIME_KEY, CoreMetrics.TEST_SUCCESS_DENSITY_KEY, CoreMetrics.TEST_FAILURES_KEY, CoreMetrics.TEST_ERRORS_KEY, CoreMetrics.SKIPPED_TESTS_KEY})
@UserRole(UserRole.CODEVIEWER)
public class TestsViewerDefinition extends GwtPage {
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
index 8af552c5f52..944fc9a572d 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
@@ -207,7 +207,6 @@ public class CorePlugin implements Plugin {
extensions.add(JavaColorizerFormat.class);
// batch
- extensions.add(JavaSourceImporter.class);
extensions.add(ProfileSensor.class);
extensions.add(ProjectLinksSensor.class);
extensions.add(AsynchronousMeasuresSensor.class);
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java
index a6066489274..b65b0500747 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java
@@ -20,6 +20,7 @@
package org.sonar.plugins.core.batch;
import org.junit.Test;
+import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Resource;
import static org.hamcrest.core.Is.is;
@@ -59,7 +60,7 @@ public class ExcludedResourceFilterTest {
ExcludedResourceFilter filter = new ExcludedResourceFilter(new String[]{"**/foo/*.java", "**/bar/*"});
Resource unitTest = mock(Resource.class);
- when(unitTest.getQualifier()).thenReturn(Resource.QUALIFIER_UNIT_TEST_CLASS);
+ when(unitTest.getQualifier()).thenReturn(Qualifiers.UNIT_TEST_FILE);
// match exclusion pattern
when(unitTest.matchFilePattern("**/bar/*")).thenReturn(true);
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/JavaSourceImporter.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/JavaSourceImporter.java
index 1b8f32a8892..87e7699ba88 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/JavaSourceImporter.java
+++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/JavaSourceImporter.java
@@ -17,35 +17,28 @@
* 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.core.sensors;
+package org.sonar.plugins.squid;
-import org.sonar.api.batch.AbstractSourceImporter;
-import org.sonar.api.batch.Phase;
-import org.sonar.api.batch.ResourceCreationLock;
+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;
-@Phase(name = Phase.Name.PRE)
+@DependsUpon(classes=SquidSensor.class)
+@DependedUpon(JavaUtils.BARRIER_AFTER_SQUID)
public class JavaSourceImporter extends AbstractSourceImporter {
- private ResourceCreationLock lock;
- public JavaSourceImporter(ResourceCreationLock lock) {
+ public JavaSourceImporter() {
super(Java.INSTANCE);
- this.lock = lock;
}
@Override
protected Resource createResource(File file, List<File> sourceDirs, boolean unitTest) {
- return (file != null && !file.getName().contains("$")) ? JavaFile.fromIOFile(file, sourceDirs, unitTest) : null;
- }
-
- @Override
- protected void onFinished() {
- lock.lock();
+ return file != null ? JavaFile.fromIOFile(file, sourceDirs, unitTest) : null;
}
@Override
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-core-plugin/src/test/java/org/sonar/plugins/core/sensors/JavaSourceImporterTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/JavaSourceImporterTest.java
index 0b47543b33a..c6667a6920e 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/JavaSourceImporterTest.java
+++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/JavaSourceImporterTest.java
@@ -17,16 +17,10 @@
* 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.core.sensors;
+package org.sonar.plugins.squid;
import org.apache.commons.io.FileUtils;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.mock;
-
import org.junit.Test;
-import org.sonar.api.batch.ResourceCreationLock;
import org.sonar.api.resources.JavaFile;
import org.sonar.api.resources.JavaPackage;
import org.sonar.api.resources.Resource;
@@ -36,11 +30,14 @@ 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 shouldCreateResource() throws IOException {
- JavaSourceImporter importer = new JavaSourceImporter(mock(ResourceCreationLock.class));
+ 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"));
@@ -48,21 +45,13 @@ public class JavaSourceImporterTest {
}
@Test
- public void shouldCreateTestResource() throws IOException {
- JavaSourceImporter importer = new JavaSourceImporter(mock(ResourceCreationLock.class));
+ 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));
}
- @Test
- public void doNotSaveInnerClasses() throws IOException {
- // example : https://svn.apache.org/repos/asf/geronimo/server/trunk/plugins/corba/geronimo-corba/src/test/java/org/apache/geronimo/corba/compiler/other/Generic$Interface.java
- JavaSourceImporter importer = new JavaSourceImporter(mock(ResourceCreationLock.class));
- Resource resource = importer.createResource(new File(newDir("tests"), "/Generic$Interface.java"), Arrays.asList(newDir("tests")), true);
- assertThat(resource, nullValue());
- }
-
private File newDir(String relativePath) throws IOException {
File target = new File("target", relativePath);
FileUtils.forceMkdir(target);
diff --git a/plugins/sonar-surefire-plugin/src/test/java/org/sonar/plugins/surefire/SurefireSensorTest.java b/plugins/sonar-surefire-plugin/src/test/java/org/sonar/plugins/surefire/SurefireSensorTest.java
index e21df1d9648..450570ff6bc 100644
--- a/plugins/sonar-surefire-plugin/src/test/java/org/sonar/plugins/surefire/SurefireSensorTest.java
+++ b/plugins/sonar-surefire-plugin/src/test/java/org/sonar/plugins/surefire/SurefireSensorTest.java
@@ -19,19 +19,6 @@
*/
package org.sonar.plugins.surefire;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
import org.apache.commons.lang.ObjectUtils;
import org.custommonkey.xmlunit.DetailedDiff;
import org.custommonkey.xmlunit.Diff;
@@ -46,6 +33,7 @@ import org.sonar.api.measures.Metric;
import org.sonar.api.resources.Java;
import org.sonar.api.resources.JavaFile;
import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
import org.sonar.api.test.IsMeasure;
import org.sonar.api.test.IsResource;
import org.sonar.api.test.MavenTestUtils;
@@ -55,6 +43,15 @@ import java.io.FileReader;
import java.io.StringReader;
import java.net.URISyntaxException;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
+
public class SurefireSensorTest {
@Test
@@ -94,7 +91,7 @@ public class SurefireSensorTest {
new SurefireSensor().collect(newJarProject(), context, new File(getClass().getResource(
"/org/sonar/plugins/surefire/SurefireSensorTest/doNotInsertZeroTestsOnClasses/").toURI()));
- verify(context, never()).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, JavaFile.QUALIFIER_UNIT_TEST_CLASS)),
+ verify(context, never()).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, Qualifiers.UNIT_TEST_FILE)),
(Metric) anyObject(), anyDouble());
}
@@ -123,11 +120,11 @@ public class SurefireSensorTest {
new SurefireSensor().collect(newJarProject(), context, new File(getClass().getResource(
"/org/sonar/plugins/surefire/SurefireSensorTest/many-results/").toURI()));
- verify(context, times(6)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, JavaFile.QUALIFIER_UNIT_TEST_CLASS)),
+ verify(context, times(6)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, Qualifiers.UNIT_TEST_FILE)),
eq(CoreMetrics.TESTS), anyDouble());
- verify(context, times(36)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, JavaFile.QUALIFIER_UNIT_TEST_CLASS)),
+ verify(context, times(36)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, Qualifiers.UNIT_TEST_FILE)),
(Metric) anyObject(), anyDouble());
- verify(context, times(6)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, JavaFile.QUALIFIER_UNIT_TEST_CLASS)),
+ verify(context, times(6)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, Qualifiers.UNIT_TEST_FILE)),
argThat(new IsMeasure(CoreMetrics.TEST_DATA)));
verify(context)
@@ -147,13 +144,13 @@ public class SurefireSensorTest {
"/org/sonar/plugins/surefire/SurefireSensorTest/shouldHandleTestSuiteDetails/").toURI()));
// 3 classes, 6 measures by class
- verify(context, times(3)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, JavaFile.QUALIFIER_UNIT_TEST_CLASS)),
+ verify(context, times(3)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, Qualifiers.UNIT_TEST_FILE)),
eq(CoreMetrics.SKIPPED_TESTS), anyDouble());
- verify(context, times(3)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, JavaFile.QUALIFIER_UNIT_TEST_CLASS)),
+ verify(context, times(3)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, Qualifiers.UNIT_TEST_FILE)),
eq(CoreMetrics.TESTS), anyDouble());
- verify(context, times(18)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, JavaFile.QUALIFIER_UNIT_TEST_CLASS)),
+ verify(context, times(18)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, Qualifiers.UNIT_TEST_FILE)),
(Metric) anyObject(), anyDouble());
- verify(context, times(3)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, JavaFile.QUALIFIER_UNIT_TEST_CLASS)),
+ verify(context, times(3)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, Qualifiers.UNIT_TEST_FILE)),
argThat(new IsMeasure(CoreMetrics.TEST_DATA)));
verify(context).saveMeasure(eq(new JavaFile("org.sonar.core.ExtensionsFinderTest", true)), eq(CoreMetrics.TESTS), eq(4d));
@@ -191,14 +188,14 @@ public class SurefireSensorTest {
"/org/sonar/plugins/surefire/SurefireSensorTest/shouldSaveErrorsAndFailuresInXML/").toURI()));
// 1 classes, 6 measures by class
- verify(context, times(1)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, JavaFile.QUALIFIER_UNIT_TEST_CLASS)),
+ verify(context, times(1)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, Qualifiers.UNIT_TEST_FILE)),
eq(CoreMetrics.SKIPPED_TESTS), anyDouble());
- verify(context, times(1)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, JavaFile.QUALIFIER_UNIT_TEST_CLASS)),
+ verify(context, times(1)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, Qualifiers.UNIT_TEST_FILE)),
eq(CoreMetrics.TESTS), anyDouble());
- verify(context, times(6)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, JavaFile.QUALIFIER_UNIT_TEST_CLASS)),
+ verify(context, times(6)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, Qualifiers.UNIT_TEST_FILE)),
(Metric) anyObject(), anyDouble());
- verify(context, times(1)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, JavaFile.QUALIFIER_UNIT_TEST_CLASS)),
+ verify(context, times(1)).saveMeasure(argThat(new IsResource(JavaFile.SCOPE_ENTITY, Qualifiers.UNIT_TEST_FILE)),
argThat(new IsMeasure(CoreMetrics.TEST_DATA)));
verify(context).saveMeasure(eq(new JavaFile("org.sonar.core.ExtensionsFinderTest", true)),
@@ -283,7 +280,7 @@ public class SurefireSensorTest {
public boolean matches(Object obj) {
try {
- if ( !ObjectUtils.equals(CoreMetrics.TEST_DATA, ((Measure) obj).getMetric())) {
+ if (!ObjectUtils.equals(CoreMetrics.TEST_DATA, ((Measure) obj).getMetric())) {
return false;
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultResourceCreationLock.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultResourceCreationLock.java
index 93b33f6b53a..49e1244c191 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/DefaultResourceCreationLock.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultResourceCreationLock.java
@@ -19,6 +19,7 @@
*/
package org.sonar.batch;
+import org.apache.commons.configuration.Configuration;
import org.sonar.api.batch.ResourceCreationLock;
/**
@@ -30,6 +31,14 @@ import org.sonar.api.batch.ResourceCreationLock;
public final class DefaultResourceCreationLock implements ResourceCreationLock {
private boolean locked = false;
+ private boolean failWhenLocked=false;
+
+ public DefaultResourceCreationLock() {
+ }
+
+ public DefaultResourceCreationLock(Configuration configuration) {
+ this.failWhenLocked = configuration.getBoolean("sonar.hardIndexLock", false);
+ }
public boolean isLocked() {
return locked;
@@ -46,4 +55,11 @@ public final class DefaultResourceCreationLock implements ResourceCreationLock {
locked = false;
}
+ public boolean isFailWhenLocked() {
+ return failWhenLocked;
+ }
+
+ public void setFailWhenLocked(boolean b) {
+ this.failWhenLocked = b;
+ }
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
index b63bef696fd..5660bf44ade 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
@@ -460,9 +460,7 @@ public final class DefaultIndex extends SonarIndex {
return bucket;
}
- if (lock.isLocked() && !ResourceUtils.isLibrary(resource)) {
- LOG.warn("Resource will be ignored in next Sonar versions, index is locked: " + resource);
- }
+ checkLock(resource);
Resource parent = null;
if (!ResourceUtils.isLibrary(resource)) {
@@ -487,6 +485,14 @@ public final class DefaultIndex extends SonarIndex {
return bucket;
}
+ private void checkLock(Resource resource) {
+ if (lock.isLocked() && !ResourceUtils.isLibrary(resource)) {
+ if (lock.isFailWhenLocked()) {
+ throw new SonarException("Index is locked, resource can not be indexed: " + resource);
+ }
+ LOG.warn("Resource will be ignored in next Sonar versions, index is locked: " + resource);
+ }
+ }
public boolean isExcluded(Resource reference) {
Bucket bucket = getBucket(reference, true);
diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
index 25f6bcb6cc1..e90cd8a9b61 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
@@ -24,9 +24,13 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.sonar.api.batch.ResourceFilter;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.MeasuresFilters;
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.*;
+import org.sonar.api.utils.SonarException;
import org.sonar.batch.DefaultResourceCreationLock;
import org.sonar.batch.ProjectTree;
import org.sonar.batch.ResourceFilters;
@@ -36,14 +40,20 @@ import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class DefaultIndexTest {
private DefaultIndex index = null;
+ private DefaultResourceCreationLock lock;
@Before
public void createIndex() {
- index = new DefaultIndex(mock(PersistenceManager.class), new DefaultResourceCreationLock(), mock(ProjectTree.class), mock(MetricFinder.class));
+ lock = new DefaultResourceCreationLock();
+ MetricFinder metricFinder = mock(MetricFinder.class);
+ when(metricFinder.findByKey("ncloc")).thenReturn(CoreMetrics.NCLOC);
+
+ index = new DefaultIndex(mock(PersistenceManager.class), lock, mock(ProjectTree.class), metricFinder);
Project project = new Project("project");
ResourceFilter filter = new ResourceFilter() {
@@ -126,10 +136,25 @@ public class DefaultIndexTest {
}
+ /**
+ * Only a warning is logged when index is locked.
+ */
@Test
- @Ignore("TODO: should it be really possible")
- public void shouldIndexDirectChildOfProject() {
+ public void shouldIndexEvenIfLocked() {
+ lock.lock();
+
+ Directory dir = new Directory("org/foo");
+ assertThat(index.index(dir), is(true));
+ assertThat(index.isIndexed(dir), is(true));
+ }
+
+ @Test(expected = SonarException.class)
+ public void shouldFailIfIndexingAndLocked() {
+ lock.setFailWhenLocked(true);
+ lock.lock();
+ Directory dir = new Directory("org/foo");
+ index.index(dir);
}
@Test
@@ -139,4 +164,13 @@ public class DefaultIndexTest {
assertThat(index.isIndexed(file), is(false));
assertThat(index.isExcluded(file), is(true));
}
+
+ @Test
+ public void shouldIndexResourceWhenAddingMeasure() {
+ Resource dir = new Directory("org/foo");
+ index.addMeasure(dir, new Measure("ncloc").setValue(50.0));
+
+ assertThat(index.isIndexed(dir), is(true));
+ assertThat(index.getMeasures(dir, MeasuresFilters.metric("ncloc")).getIntValue(), is(50));
+ }
}
diff --git a/sonar-java-api/src/main/java/org/sonar/java/api/JavaClass.java b/sonar-java-api/src/main/java/org/sonar/java/api/JavaClass.java
index 0e2bc281479..563879e23bb 100644
--- a/sonar-java-api/src/main/java/org/sonar/java/api/JavaClass.java
+++ b/sonar-java-api/src/main/java/org/sonar/java/api/JavaClass.java
@@ -20,16 +20,15 @@
package org.sonar.java.api;
import org.apache.commons.lang.StringUtils;
-import org.sonar.api.resources.Java;
-import org.sonar.api.resources.Language;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.*;
/**
* @since 2.6
*/
public final class JavaClass extends Resource {
+ public static final String SCOPE = Scopes.TYPE;
+ public static final String QUALIFIER = Qualifiers.CLASS;
public static final int UNKNOWN_LINE = -1;
private int fromLine = UNKNOWN_LINE;
@@ -87,12 +86,12 @@ public final class JavaClass extends Resource {
@Override
public String getScope() {
- return null;
+ return SCOPE;
}
@Override
public String getQualifier() {
- return Qualifiers.CLASS;
+ return QUALIFIER;
}
@Override
diff --git a/sonar-java-api/src/main/java/org/sonar/java/api/JavaMethod.java b/sonar-java-api/src/main/java/org/sonar/java/api/JavaMethod.java
index 6cf02551be6..743b3fa4069 100644
--- a/sonar-java-api/src/main/java/org/sonar/java/api/JavaMethod.java
+++ b/sonar-java-api/src/main/java/org/sonar/java/api/JavaMethod.java
@@ -20,16 +20,16 @@
package org.sonar.java.api;
import org.apache.commons.lang.StringUtils;
-import org.sonar.api.resources.Java;
-import org.sonar.api.resources.Language;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.*;
/**
* @since 2.6
*/
public final class JavaMethod extends Resource {
+ public static final String SCOPE = Scopes.BLOCK_UNIT;
+ public static final String QUALIFIER = Qualifiers.METHOD;
+
public static final int UNKNOWN_LINE = -1;
private static final String CLASS_SEPARATOR = "#";
@@ -88,12 +88,12 @@ public final class JavaMethod extends Resource {
@Override
public String getScope() {
- return null;
+ return SCOPE;
}
@Override
public String getQualifier() {
- return Qualifiers.METHOD;
+ return QUALIFIER;
}
@Override
diff --git a/sonar-java-api/src/main/java/org/sonar/java/api/JavaUtils.java b/sonar-java-api/src/main/java/org/sonar/java/api/JavaUtils.java
index a1925501b5d..dad567cc1e3 100644
--- a/sonar-java-api/src/main/java/org/sonar/java/api/JavaUtils.java
+++ b/sonar-java-api/src/main/java/org/sonar/java/api/JavaUtils.java
@@ -25,6 +25,17 @@ public final class JavaUtils {
public static final String PACKAGE_SEPARATOR = ".";
+ /**
+ * All sensors executed after this barrier are sure that all Java resources are indexed.
+ */
+ public static final String BARRIER_BEFORE_SQUID = "BEFORE_SQUID";
+
+ /**
+ * Sensors executed before this barrier must not rely on index. No Java resources are indexed.
+ * Value is 'squid' in order to be backward-compatible with Sensor.FLAG_SQUID_ANALYSIS.
+ */
+ public static final String BARRIER_AFTER_SQUID = "squid";
+
private JavaUtils() {
// only static methods
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java
index b11a96f5655..0c796b83ec0 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java
@@ -21,10 +21,7 @@ package org.sonar.api.batch;
import org.apache.commons.io.FileUtils;
import org.sonar.api.CoreProperties;
-import org.sonar.api.resources.Language;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.ProjectFileSystem;
-import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.*;
import org.sonar.api.utils.SonarException;
import java.io.File;
@@ -34,7 +31,7 @@ import java.util.List;
/**
* A pre-implementation for a sensor that imports sources
- *
+ *
* @since 1.10
*/
@Phase(name = Phase.Name.PRE)
@@ -103,7 +100,7 @@ public abstract class AbstractSourceImporter implements Sensor {
if (resource != null) {
resource.setLanguage(language);
if (unitTest) {
- resource.setQualifier(Resource.QUALIFIER_UNIT_TEST_CLASS);
+ resource.setQualifier(Qualifiers.UNIT_TEST_FILE);
}
}
return resource;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java
index 8811492b955..06ae5ae80fd 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java
@@ -124,6 +124,12 @@ public abstract class SonarIndex implements DirectedGraphAccessor<Resource, Depe
addViolation(violation, false);
}
+ /**
+ * Warning: the resource is automatically indexed for backward-compatibility, but it should be explictly
+ * indexed before. Next versions will deactivate this automatic indexation.
+ *
+ * @throws SonarException if the metric is unknown.
+ */
public abstract Measure addMeasure(Resource resource, Measure measure);
public abstract Dependency addDependency(Dependency dependency);
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java
index 434fe55e23c..2b74a78a500 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java
@@ -45,7 +45,11 @@ public final class MeasuresFilters {
}
public static MeasuresFilter<Measure> metric(final Metric metric) {
- return new MetricFilter<Measure>(metric) {
+ return metric(metric.getKey());
+ }
+
+ public static MeasuresFilter<Measure> metric(final String metricKey) {
+ return new MetricFilter<Measure>(metricKey) {
public Measure filter(Collection<Measure> measures) {
if (measures == null) {
@@ -53,7 +57,7 @@ public final class MeasuresFilters {
}
for (Measure measure : measures) {
if (measure.getClass().equals(Measure.class) &&
- measure.getMetricKey().equals(metric.getKey()) &&
+ measure.getMetricKey().equals(metricKey) &&
measure.getCharacteristic()==null) {
return measure;
}
@@ -165,6 +169,10 @@ public final class MeasuresFilters {
this.metricKey = metric.getKey();
}
+ protected MetricFilter(String metricKey) {
+ this.metricKey = metricKey;
+ }
+
public String filterOnMetricKey() {
return metricKey;
}
diff --git a/sonar-server/src/main/java/org/sonar/server/filters/Filter.java b/sonar-server/src/main/java/org/sonar/server/filters/Filter.java
index e50703f6353..d2c864ff181 100644
--- a/sonar-server/src/main/java/org/sonar/server/filters/Filter.java
+++ b/sonar-server/src/main/java/org/sonar/server/filters/Filter.java
@@ -23,6 +23,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
+import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Resource;
import java.util.List;
@@ -375,6 +376,6 @@ public class Filter {
public static Filter createForAllQualifiers() {
return new Filter().setQualifiers(Resource.QUALIFIER_VIEW, Resource.QUALIFIER_SUBVIEW,
Resource.QUALIFIER_PROJECT, Resource.QUALIFIER_MODULE, Resource.QUALIFIER_DIRECTORY, Resource.QUALIFIER_PACKAGE,
- Resource.QUALIFIER_FILE, Resource.QUALIFIER_CLASS, Resource.QUALIFIER_UNIT_TEST_CLASS, Resource.QUALIFIER_LIB);
+ Resource.QUALIFIER_FILE, Resource.QUALIFIER_CLASS, Qualifiers.UNIT_TEST_FILE, Resource.QUALIFIER_LIB);
}
}
diff --git a/tests/integration/tests/build.xml b/tests/integration/tests/build.xml
index 75bad16d20f..29f2fcfe14a 100644
--- a/tests/integration/tests/build.xml
+++ b/tests/integration/tests/build.xml
@@ -179,6 +179,7 @@
<arg value="-Dsonar.jdbc.driver=${sonar.jdbc.driver}"/>
<arg value="-Dsonar.jdbc.username=${sonar.jdbc.username}"/>
<arg value="-Dsonar.jdbc.password=${sonar.jdbc.password}"/>
+ <arg value="-Dsonar.hardIndexLock=true"/>
</exec>
<exec failonerror="@{failonerror}" executable="${maven.home}/bin/mvn" osfamily="unix">
<arg line="org.codehaus.mojo:sonar-maven-plugin:1.0-beta-2:sonar @{args} -B -e"/>
@@ -187,6 +188,7 @@
<arg value="-Dsonar.jdbc.driver=${sonar.jdbc.driver}"/>
<arg value="-Dsonar.jdbc.username=${sonar.jdbc.username}"/>
<arg value="-Dsonar.jdbc.password=${sonar.jdbc.password}"/>
+ <arg value="-Dsonar.hardIndexLock=true"/>
</exec>
</sequential>
</macrodef>