001/* 002 * SonarQube 003 * Copyright (C) 2009-2017 SonarSource SA 004 * mailto:info AT sonarsource DOT com 005 * 006 * This program 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 * This program 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 License 017 * along with this program; if not, write to the Free Software Foundation, 018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 019 */ 020package org.sonar.api; 021 022import org.sonar.api.batch.ScannerSide; 023import org.sonar.api.batch.sensor.Sensor; 024import org.sonar.api.batch.sensor.SensorContext; 025import org.sonar.api.ce.ComputeEngineSide; 026import org.sonar.api.server.ServerSide; 027import org.sonar.api.utils.Version; 028import org.sonarsource.api.sonarlint.SonarLintSide; 029 030/** 031 * Information about runtime environment. 032 * 033 * <p> 034 * A usage for plugins is to benefit from new APIs 035 * while keeping backward-compatibility with previous versions of SonarQube 036 * or SonarLint. 037 * </p> 038 * 039 * <p> 040 * Example: a plugin extension wants to use a new feature of API 6.1 without 041 * breaking compatibility with version 6.0 at runtime. This new feature 042 * would be enabled only in 6.1 and greater runtimes. 043 * </p> 044 * <pre> 045 * // Component provided by sonar-plugin-api 046 * // @since 6.0 047 * public interface AnApi { 048 * // implicitly since 6.0 049 * public void foo(); 050 * 051 * // @since 6.1 052 * public void bar(); 053 * } 054 * 055 * // Plugin extension 056 * public class MyExtension { 057 * private final SonarRuntime sonarRuntime; 058 * private final AnApi api; 059 * 060 * public MyExtension(SonarRuntime sonarRuntime, AnApi api) { 061 * this.sonarRuntime = sonarRuntime; 062 * this.api = api; 063 * } 064 * 065 * public void doSomething() { 066 * // assume that minimal supported runtime is 6.0 067 * api.foo(); 068 * 069 * if (sonarRuntime.getApiVersion().isGreaterThanOrEqual(Version.create(6, 1))) { 070 * api.bar(); 071 * } 072 * } 073 * } 074 * </pre> 075 * 076 * 077 * <p> 078 * Note that {@link Sensor} extensions can directly get {@link SonarRuntime} through 079 * {@link SensorContext#runtime()}, without using constructor injection: 080 * </p> 081 * <pre> 082 * public class MySensor implements Sensor { 083 * 084 * public void execute(SensorContext context) { 085 * if (context.runtime().getApiVersion().isGreaterThanOrEqual(Version.create(6, 1)) { 086 * context.newMethodIntroducedIn6_0(); 087 * } 088 * } 089 * 090 * } 091 * </pre> 092 * 093 * <p> 094 * The minimal supported version of plugin API is verified at runtime. As plugin is built 095 * with sonar-plugin-api 6.1, we assume that the plugin requires v6.1 or greater at runtime. 096 * For this reason the plugin must override the minimal supported version 097 * in the configuration of sonar-packaging-maven-plugin 1.16+: 098 * <p> 099 * <pre> 100 * <packaging>sonar-plugin</packaging> 101 * 102 * <dependencies> 103 * <dependency> 104 * <groupId>org.sonarsource.sonarqube</groupId> 105 * <artifactId>sonar-plugin-api</artifactId> 106 * <version>6.1</version> 107 * <scope>provided</scope> 108 * </dependency> 109 * </dependencies> 110 * 111 * <build> 112 * <plugins> 113 * <plugin> 114 * <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId> 115 * <artifactId>sonar-packaging-maven-plugin</artifactId> 116 * <version>1.16</version> 117 * <extensions>true</extensions> 118 * <configuration> 119 * <!-- Override the default value 6.0 which is guessed from sonar-plugin-api dependency --> 120 * <sonarQubeMinVersion>6.0</sonarQubeMinVersion> 121 * </configuration> 122 * </plugin> 123 * </plugins> 124 * </build> 125 * </pre> 126 * 127 * <p> 128 * As this component was introduced in version 6.0, the pattern described above can't be 129 * exactly applied when plugin must support version 5.6 Long Term Support. In this case plugin 130 * should use {@link SonarQubeVersion}, for example through {@link Plugin.Context#getSonarQubeVersion()} or 131 * {@link SensorContext#getSonarQubeVersion()}. 132 * </p> 133 * 134 * <p> 135 * Unit tests of plugin extensions can create instances of {@link SonarRuntime} 136 * via {@link org.sonar.api.internal.SonarRuntimeImpl}. 137 * </p> 138 * @since 6.0 139 */ 140@ScannerSide 141@ServerSide 142@ComputeEngineSide 143@SonarLintSide 144public interface SonarRuntime { 145 146 /** 147 * Version of API (sonar-plugin-api artifact) at runtime. 148 * It can be helpful to call some API classes/methods without checking their availability at 149 * runtime by using reflection. 150 * <br/> 151 * Since 6.3, the returned version includes the build number in the fourth field, for 152 * example {@code "6.3.0.12345"}. 153 */ 154 Version getApiVersion(); 155 156 /** 157 * The product being executed at runtime. It targets analysers so that they can implement 158 * different behaviours in SonarQube and SonarLint. 159 */ 160 SonarProduct getProduct(); 161 162 /** 163 * The SonarQube stack being executed at runtime. 164 * @throws UnsupportedOperationException if {@link #getProduct()} is not equal to {@link SonarProduct#SONARQUBE} 165 */ 166 SonarQubeSide getSonarQubeSide(); 167 168}