diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2016-03-24 15:53:36 +0100 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2016-03-30 11:42:16 +0200 |
commit | 10955ec396a053d596a40ac3fdf7ca73dd911327 (patch) | |
tree | c390cd08b8b44656206306c94213204baeec737c /sonar-plugin-api | |
parent | 946a448c08ccc10ad1c0af778ae5d9f179655ef8 (diff) | |
download | sonarqube-10955ec396a053d596a40ac3fdf7ca73dd911327.tar.gz sonarqube-10955ec396a053d596a40ac3fdf7ca73dd911327.zip |
SONAR-7458 Expose SQ Version in SensorContext
Diffstat (limited to 'sonar-plugin-api')
7 files changed, 179 insertions, 9 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/SonarQubeVersion.java b/sonar-plugin-api/src/main/java/org/sonar/api/SonarQubeVersion.java index 0889546d04e..5387d3ef765 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/SonarQubeVersion.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/SonarQubeVersion.java @@ -21,6 +21,7 @@ package org.sonar.api; import javax.annotation.concurrent.Immutable; import org.sonar.api.batch.BatchSide; +import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.server.ServerSide; import org.sonar.api.utils.Version; @@ -31,10 +32,24 @@ import static java.util.Objects.requireNonNull; * Version of SonarQube at runtime. This component can be injected as a dependency * of plugin extensions. The main usage for a plugin is to benefit from new APIs * while keeping backward-compatibility with previous versions of SonarQube. - - * Example: a plugin needs to use an API introduced in version 5.6 ({@code AnApi} in the following + * <br><br> + * + * Example 1: a {@link Sensor} wants to use an API introduced in version 5.5 and still requires to support older versions + * at runtime. + * <pre> + * public class MySensor implements Sensor { + * + * public void execute(SensorContext context) { + * if (context.getSonarQubeVersion().isGreaterThanOrEqual(SonarQubeVersion.V5_5)) { + * context.newMethodIntroducedIn5_5(); + * } + * } + * } + * </pre> + * + * Example 2: a plugin needs to use an API introduced in version 5.6 ({@code AnApi} in the following * snippet) and still requires to support version 5.5 at runtime. - * <p></p> + * <br> * <pre> * // Component provided by sonar-plugin-api * // @since 5.5 @@ -45,7 +60,7 @@ import static java.util.Objects.requireNonNull; * // @since 5.6 * public void bar(); * } - * + * * // Component provided by plugin * public class MyExtension { * private final SonarQubeVersion sonarQubeVersion; @@ -131,6 +146,7 @@ public class SonarQubeVersion { } public boolean isGreaterThanOrEqual(Version than) { - return this.version.compareTo(than) >= 0; + return this.version.isGreaterThanOrEqual(than); } + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java index 3d49859470e..1c159c38b78 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java @@ -33,6 +33,7 @@ import org.sonar.api.batch.sensor.issue.NewIssue; import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.measure.NewMeasure; import org.sonar.api.config.Settings; +import org.sonar.api.utils.Version; /** * See {@link Sensor#execute(SensorContext)} @@ -62,6 +63,11 @@ public interface SensorContext { */ InputModule module(); + /** + * @since 5.5 + */ + Version getSonarQubeVersion(); + // ----------- MEASURES -------------- /** diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java index 24a06a241bd..b0c19108f16 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java @@ -24,6 +24,7 @@ import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; import java.io.File; import java.io.Serializable; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -32,6 +33,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.CheckForNull; +import org.sonar.api.SonarQubeVersion; import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.InputModule; import org.sonar.api.batch.fs.internal.DefaultFileSystem; @@ -57,7 +59,10 @@ import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.measure.NewMeasure; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.config.Settings; +import org.sonar.api.internal.SonarQubeVersionFactory; import org.sonar.api.measures.Metric; +import org.sonar.api.utils.System2; +import org.sonar.api.utils.Version; import org.sonar.duplications.internal.pmd.TokensLine; /** @@ -76,16 +81,22 @@ public class SensorContextTester implements SensorContext { private ActiveRules activeRules; private InMemorySensorStorage sensorStorage; private InputModule module; + private SonarQubeVersion sqVersion; - private SensorContextTester(File moduleBaseDir) { + private SensorContextTester(Path moduleBaseDir) { this.settings = new Settings(); this.fs = new DefaultFileSystem(moduleBaseDir); this.activeRules = new ActiveRulesBuilder().build(); this.sensorStorage = new InMemorySensorStorage(); this.module = new DefaultInputModule("projectKey"); + this.sqVersion = SonarQubeVersionFactory.create(System2.INSTANCE); } public static SensorContextTester create(File moduleBaseDir) { + return new SensorContextTester(moduleBaseDir.toPath()); + } + + public static SensorContextTester create(Path moduleBaseDir) { return new SensorContextTester(moduleBaseDir); } @@ -94,8 +105,9 @@ public class SensorContextTester implements SensorContext { return settings; } - public void setSettings(Settings settings) { + public SensorContextTester setSettings(Settings settings) { this.settings = settings; + return this; } @Override @@ -103,8 +115,9 @@ public class SensorContextTester implements SensorContext { return fs; } - public void setFileSystem(DefaultFileSystem fs) { + public SensorContextTester setFileSystem(DefaultFileSystem fs) { this.fs = fs; + return this; } @Override @@ -112,8 +125,27 @@ public class SensorContextTester implements SensorContext { return activeRules; } - public void setActiveRules(ActiveRules activeRules) { + public SensorContextTester setActiveRules(ActiveRules activeRules) { this.activeRules = activeRules; + return this; + } + + /** + * Default value is the version of this API. You can override it + * using {@link #setSonarQubeVersion(Version)} to test your Sensor behavior. + * @since 5.5 + */ + @Override + public Version getSonarQubeVersion() { + return sqVersion.get(); + } + + /** + * @since 5.5 + */ + public SensorContextTester setSonarQubeVersion(Version version) { + this.sqVersion = new SonarQubeVersion(version); + return this; } @Override diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarQubeVersionFactory.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarQubeVersionFactory.java new file mode 100644 index 00000000000..db85c3feaf1 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarQubeVersionFactory.java @@ -0,0 +1,50 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.api.internal; + +import com.google.common.io.Resources; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import org.sonar.api.SonarQubeVersion; +import org.sonar.api.utils.System2; +import org.sonar.api.utils.Version; + +/** + * For internal use only. + */ +public class SonarQubeVersionFactory { + + private static final String FILE_PATH = "/sq-version.txt"; + + private SonarQubeVersionFactory() { + // prevents instantiation + } + + public static SonarQubeVersion create(System2 system) { + try { + URL url = system.getResource(FILE_PATH); + String versionInFile = Resources.toString(url, StandardCharsets.UTF_8); + return new SonarQubeVersion(Version.parse(versionInFile)); + } catch (IOException e) { + throw new IllegalStateException("Can not load " + FILE_PATH + " from classpath", e); + } + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java index dcd96d9cbb4..50813e97c0e 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java @@ -144,6 +144,10 @@ public class Version implements Comparable<Version> { return parseInt(sequence); } + public boolean isGreaterThanOrEqual(Version than) { + return this.compareTo(than) >= 0; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/SonarQubeVersionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/SonarQubeVersionTest.java index 0cc786c3ba4..50bc4b1c2ec 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/SonarQubeVersionTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/SonarQubeVersionTest.java @@ -19,13 +19,18 @@ */ package org.sonar.api; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.sonar.api.utils.Version; import static org.assertj.core.api.Assertions.assertThat; public class SonarQubeVersionTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Test public void isGte() { Version version = Version.parse("1.2.3"); @@ -35,4 +40,5 @@ public class SonarQubeVersionTest { assertThat(qubeVersion.isGreaterThanOrEqual(Version.parse("1.1"))).isTrue(); assertThat(qubeVersion.isGreaterThanOrEqual(Version.parse("1.3"))).isFalse(); } + } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarQubeVersionFactoryTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarQubeVersionFactoryTest.java new file mode 100644 index 00000000000..d37f7693d10 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarQubeVersionFactoryTest.java @@ -0,0 +1,56 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.api.internal; + +import java.io.File; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.SonarQubeVersion; +import org.sonar.api.utils.System2; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +public class SonarQubeVersionFactoryTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void create() { + SonarQubeVersion version = SonarQubeVersionFactory.create(System2.INSTANCE); + assertThat(version).isNotNull(); + assertThat(version.get().major()).isGreaterThanOrEqualTo(5); + } + + @Test + public void throw_ISE_if_fail_to_load_version() throws Exception { + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Can not load /sq-version.txt from classpath"); + + System2 system = spy(System2.class); + when(system.getResource(anyString())).thenReturn(new File("target/unknown").toURI().toURL()); + SonarQubeVersionFactory.create(system); + } + +} |