Browse Source

SONAR-10541, SONAR-10331 Drop compatibility mode and clean plugin classloader

tags/7.5
Julien HENRY 5 years ago
parent
commit
fdf0f2f893
28 changed files with 69 additions and 253 deletions
  1. 2
    1
      server/sonar-ce-task-projectanalysis/build.gradle
  2. 2
    0
      server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java
  3. 13
    3
      server/sonar-server-common/src/main/java/org/sonar/server/platform/ServerFileSystemImpl.java
  4. 2
    4
      server/sonar-server/build.gradle
  5. 0
    1
      settings.gradle
  6. 2
    2
      sonar-application/build.gradle
  7. 0
    14
      sonar-core/build.gradle
  8. 0
    13
      sonar-core/src/main/java/org/sonar/core/platform/PluginClassLoaderDef.java
  9. 7
    40
      sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderFactory.java
  10. 4
    5
      sonar-core/src/main/java/org/sonar/core/platform/PluginLoader.java
  11. 1
    20
      sonar-core/src/test/java/org/sonar/core/platform/PluginClassloaderFactoryTest.java
  12. 19
    33
      sonar-core/src/test/java/org/sonar/core/platform/PluginLoaderTest.java
  13. 1
    0
      sonar-duplications/build.gradle
  14. 0
    44
      sonar-duplications/src/main/java/org/sonar/duplications/CodeFragment.java
  15. 1
    5
      sonar-duplications/src/main/java/org/sonar/duplications/block/Block.java
  16. 1
    5
      sonar-duplications/src/main/java/org/sonar/duplications/index/ClonePart.java
  17. 1
    2
      sonar-duplications/src/main/java/org/sonar/duplications/internal/pmd/PmdBlockChunker.java
  18. 1
    0
      sonar-duplications/src/main/java/org/sonar/duplications/internal/pmd/TokenizerBridge.java
  19. 1
    4
      sonar-duplications/src/main/java/org/sonar/duplications/statement/Statement.java
  20. 3
    3
      sonar-duplications/src/test/java/org/sonar/duplications/internal/pmd/PmdBlockChunkerTest.java
  21. 1
    0
      sonar-duplications/src/test/java/org/sonar/duplications/internal/pmd/TokenizerBridgeTest.java
  22. 0
    42
      sonar-plugin-api-deps/build.gradle
  23. 0
    3
      sonar-plugin-api/build.gradle
  24. 1
    2
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java
  25. 2
    6
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/TokensLine.java
  26. 1
    1
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
  27. 2
    0
      sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/IdentityProvider.java
  28. 1
    0
      sonar-scanner-engine/build.gradle

+ 2
- 1
server/sonar-ce-task-projectanalysis/build.gradle View File

@@ -42,7 +42,8 @@ dependencies {
compileOnly project(':server:sonar-db-dao')
compileOnly project(':server:sonar-process')
compileOnly project(':server:sonar-server-common')
compileOnly project(path: ':sonar-plugin-api')
compileOnly project(':sonar-plugin-api')
compileOnly project(':sonar-duplications')

testCompile 'com.google.code.findbugs:jsr305'
testCompile 'com.h2database:h2'

+ 2
- 0
server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java View File

@@ -150,7 +150,9 @@ public class ComputeEngineContainerImplTest {
Properties properties = ProcessProperties.defaults();
File homeDir = tempFolder.newFolder();
File dataDir = new File(homeDir, "data");
dataDir.mkdirs();
File tmpDir = new File(homeDir, "tmp");
tmpDir.mkdirs();
properties.setProperty(PATH_HOME.getKey(), homeDir.getAbsolutePath());
properties.setProperty(PATH_DATA.getKey(), dataDir.getAbsolutePath());
properties.setProperty(PATH_TEMP.getKey(), tmpDir.getAbsolutePath());

+ 13
- 3
server/sonar-server-common/src/main/java/org/sonar/server/platform/ServerFileSystemImpl.java View File

@@ -20,6 +20,8 @@
package org.sonar.server.platform;

import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.picocontainer.Startable;
import org.sonar.api.config.Configuration;
import org.sonar.api.utils.log.Logger;
@@ -39,9 +41,9 @@ public class ServerFileSystemImpl implements ServerFileSystem, org.sonar.api.pla
private final File uninstallDir;

public ServerFileSystemImpl(Configuration config) {
this.homeDir = new File(config.get(PATH_HOME.getKey()).get());
this.tempDir = new File(config.get(PATH_TEMP.getKey()).get());
File dataDir = new File(config.get(PATH_DATA.getKey()).get());
this.homeDir = createDir(new File(config.get(PATH_HOME.getKey()).get()));
this.tempDir = createDir(new File(config.get(PATH_TEMP.getKey()).get()));
File dataDir = createDir(new File(config.get(PATH_DATA.getKey()).get()));
this.deployDir = new File(dataDir, "web/deploy");
this.uninstallDir = new File(getTempDir(), "uninstalled-plugins");
}
@@ -91,4 +93,12 @@ public class ServerFileSystemImpl implements ServerFileSystem, org.sonar.api.pla
return uninstallDir;
}

private static File createDir(File dir) {
try {
FileUtils.forceMkdir(dir);
return dir;
} catch (IOException e) {
throw new IllegalStateException("Fail to create directory " + dir, e);
}
}
}

+ 2
- 4
server/sonar-server/build.gradle View File

@@ -55,10 +55,8 @@ dependencies {
compile project(':server:sonar-server-common')
compile project(':sonar-core')
compile project(':sonar-scanner-protocol')
compile(project(':sonar-markdown')) {
// already shaded with sonar-plugin-api
exclude group: 'org.codehaus.sonar', module: 'sonar-channel'
}
compile project(':sonar-markdown')
compile project(':sonar-duplications')
runtime project(path: ':sonar-plugin-api', configuration: 'shadow')
compileOnly project(path: ':sonar-plugin-api')
compile project(':sonar-ws')

+ 0
- 1
settings.gradle View File

@@ -24,7 +24,6 @@ include 'sonar-core'
include 'sonar-duplications'
include 'sonar-markdown'
include 'sonar-plugin-api'
include 'sonar-plugin-api-deps'
include 'sonar-scanner-engine'
include 'sonar-scanner-engine-shaded'
include 'sonar-scanner-protocol'

+ 2
- 2
sonar-application/build.gradle View File

@@ -131,8 +131,8 @@ zip.doFirst {
}
// Check the size of the archive
zip.doLast {
def minLength = 160000000
def maxLength = 175000000
def minLength = 150000000
def maxLength = 165000000
def length = new File(distsDir, archiveName).length()
if (length < minLength)
throw new GradleException("$archiveName size ($length) too small. Min is $minLength")

+ 0
- 14
sonar-core/build.gradle View File

@@ -4,10 +4,6 @@ sonarqube {
}
}

configurations {
includeInResources
}

dependencies {
// please keep list ordered

@@ -24,8 +20,6 @@ dependencies {

compileOnly 'com.google.code.findbugs:jsr305'

includeInResources project(path: ':sonar-plugin-api-deps', configuration: 'shadow')

testCompile 'com.tngtech.java:junit-dataprovider'
testCompile 'junit:junit'
testCompile 'org.assertj:assertj-core'
@@ -36,14 +30,6 @@ dependencies {
testCompileOnly 'com.google.code.findbugs:jsr305'
}

// sonar-plugin-api.jar is copied into target JAR file
processResources {
into('/') {
from configurations.includeInResources
rename '(.*)-' + project.version + '-all.jar', '$1.jar'
}
}

// Used by sonar-db-core to run DB Unit Tests
artifactoryPublish.skip = false
publishing {

+ 0
- 13
sonar-core/src/main/java/org/sonar/core/platform/PluginClassLoaderDef.java View File

@@ -41,11 +41,6 @@ class PluginClassLoaderDef {
private final Mask mask = new Mask();
private boolean selfFirstStrategy = false;

/**
* Compatibility with API classloader as defined before version 5.2
*/
private boolean compatibilityMode = false;

PluginClassLoaderDef(String basePluginKey) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(basePluginKey));
this.basePluginKey = basePluginKey;
@@ -85,14 +80,6 @@ class PluginClassLoaderDef {
}
}

boolean isCompatibilityMode() {
return compatibilityMode;
}

void setCompatibilityMode(boolean b) {
this.compatibilityMode = b;
}

@Override
public boolean equals(@Nullable Object o) {
if (this == o) {

+ 7
- 40
sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderFactory.java View File

@@ -25,11 +25,9 @@ import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.sonar.api.batch.ScannerSide;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.TempFolder;
import org.sonar.classloader.ClassloaderBuilder;
import org.sonar.classloader.Mask;

@@ -40,8 +38,6 @@ import static org.sonar.classloader.ClassloaderBuilder.LoadingOrder.SELF_FIRST;
* Builds the graph of classloaders to be used to instantiate plugins. It deals with:
* <ul>
* <li>isolation of plugins against core classes (except api)</li>
* <li>backward-compatibility with plugins built for versions of SQ lower than 5.2. At that time
* API declared transitive dependencies that were automatically available to plugins</li>
* <li>sharing of some packages between plugins</li>
* <li>loading of the libraries embedded in plugin JAR files (directory META-INF/libs)</li>
* </ul>
@@ -54,13 +50,6 @@ public class PluginClassloaderFactory {
// underscores are used to not conflict with plugin keys (if someday a plugin key is "api")
private static final String API_CLASSLOADER_KEY = "_api_";

private final TempFolder temp;
private URL compatibilityModeJar;

public PluginClassloaderFactory(TempFolder temp) {
this.temp = temp;
}

/**
* Creates as many classloaders as requested by the input parameter.
*/
@@ -78,9 +67,6 @@ public class PluginClassloaderFactory {
for (File jar : def.getFiles()) {
builder.addURL(def.getBasePluginKey(), fileToUrl(jar));
}
if (def.isCompatibilityMode()) {
builder.addURL(def.getBasePluginKey(), extractCompatibilityModeJar());
}
exportResources(def, builder, defs);
}

@@ -120,19 +106,6 @@ public class PluginClassloaderFactory {
return getClass().getClassLoader();
}

private URL extractCompatibilityModeJar() {
if (compatibilityModeJar == null) {
File jar = temp.newFile("sonar-plugin-api-deps", "jar");
try {
FileUtils.copyURLToFile(getClass().getResource("/sonar-plugin-api-deps.jar"), jar);
compatibilityModeJar = jar.toURI().toURL();
} catch (Exception e) {
throw new IllegalStateException("Can not extract sonar-plugin-api-deps.jar to " + jar.getAbsolutePath(), e);
}
}
return compatibilityModeJar;
}

private static URL fileToUrl(File file) {
try {
return file.toURI().toURL();
@@ -149,31 +122,25 @@ public class PluginClassloaderFactory {
*/
private static Mask apiMask() {
return new Mask()
.addInclusion("org/sonar/api/")
.addInclusion("org/sonar/channel/")
.addInclusion("org/sonar/api/")
.addInclusion("org/sonar/check/")
.addInclusion("org/sonar/colorizer/")
.addInclusion("org/sonar/duplications/")
.addInclusion("org/sonar/graph/")
.addInclusion("org/sonar/plugins/emailnotifications/api/")
.addInclusion("net/sourceforge/pmd/")
.addInclusion("org/apache/maven/")
.addInclusion("org/codehaus/stax2/")
.addInclusion("org/codehaus/staxmate/")
.addInclusion("com/ctc/wstx/")
.addInclusion("org/slf4j/")
.addInclusion("javax/servlet/")

// SLF4J bridges. Do not let plugins re-initialize and configure their logging system
.addInclusion("org/apache/commons/logging/")
.addInclusion("org/apache/log4j/")
.addInclusion("ch/qos/logback/")

// required for internal libs at SonarSource
// Exposed by org.sonar.api.server.authentication.IdentityProvider
.addInclusion("javax/servlet/")

// required for some internal SonarSource plugins (billing, orchestrator, ...)
.addInclusion("org/sonar/server/platform/")
.addInclusion("org/sonar/core/persistence/")
.addInclusion("org/sonar/core/properties/")
.addInclusion("org/sonar/server/views/")

// required for commercial plugins at SonarSource
.addInclusion("com/sonarsource/plugins/license/api/")

// API exclusions

+ 4
- 5
sonar-core/src/main/java/org/sonar/core/platform/PluginLoader.java View File

@@ -50,7 +50,7 @@ public class PluginLoader {

private static final String[] DEFAULT_SHARED_RESOURCES = {"org/sonar/plugins", "com/sonar/plugins", "com/sonarsource/plugins"};

public static final Version COMPATIBILITY_MODE_MAX_VERSION = Version.create("5.2");
private static final Version COMPATIBILITY_MODE_MAX_VERSION = Version.create("5.2");

private final PluginJarExploder jarExploder;
private final PluginClassloaderFactory classloaderFactory;
@@ -96,15 +96,14 @@ public class PluginLoader {
def.setSelfFirstStrategy(info.isUseChildFirstClassLoader());
Version minSqVersion = info.getMinimalSqVersion();
boolean compatibilityMode = minSqVersion != null && minSqVersion.compareToIgnoreQualifier(COMPATIBILITY_MODE_MAX_VERSION) < 0;
def.setCompatibilityMode(compatibilityMode);
if (compatibilityMode) {
Loggers.get(getClass()).debug("API compatibility mode is enabled on plugin {} [{}] " +
"(built with API lower than {})",
info.getName(), info.getKey(), COMPATIBILITY_MODE_MAX_VERSION);
Loggers.get(getClass()).warn("API compatibility mode is no longer supported. In case of error, plugin {} [{}] should package its dependencies.",
info.getName(), info.getKey());
}
}
}
return classloadersByBasePlugin.values();

}

/**

+ 1
- 20
sonar-core/src/test/java/org/sonar/core/platform/PluginClassloaderFactoryTest.java View File

@@ -23,10 +23,8 @@ import com.sonarsource.plugins.license.api.FooBar;
import java.io.File;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.api.utils.internal.JUnitTempFolder;

import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
@@ -38,10 +36,7 @@ public class PluginClassloaderFactoryTest {
static final String BASE_PLUGIN_KEY = "base";
static final String DEPENDENT_PLUGIN_KEY = "dependent";

@Rule
public JUnitTempFolder temp = new JUnitTempFolder();

PluginClassloaderFactory factory = new PluginClassloaderFactory(temp);
PluginClassloaderFactory factory = new PluginClassloaderFactory();

@Test
public void create_isolated_classloader() {
@@ -61,20 +56,6 @@ public class PluginClassloaderFactoryTest {
assertThat(canLoadClass(classLoader, StringUtils.class.getCanonicalName())).isFalse();
}

@Test
public void create_classloader_compatible_with_with_old_api_dependencies() {
PluginClassLoaderDef def = basePluginDef();
def.setCompatibilityMode(true);
ClassLoader classLoader = factory.create(asList(def)).get(def);

// Plugin can access to API and its transitive dependencies as defined in version 5.1.
// It can not access to core classes though, even if it was possible in previous versions.
assertThat(canLoadClass(classLoader, RulesDefinition.class.getCanonicalName())).isTrue();
assertThat(canLoadClass(classLoader, StringUtils.class.getCanonicalName())).isTrue();
assertThat(canLoadClass(classLoader, BASE_PLUGIN_CLASSNAME)).isTrue();
assertThat(canLoadClass(classLoader, PluginClassloaderFactory.class.getCanonicalName())).isFalse();
}

@Test
public void classloader_exports_resources_to_other_classloaders() {
PluginClassLoaderDef baseDef = basePluginDef();

+ 19
- 33
sonar-core/src/test/java/org/sonar/core/platform/PluginLoaderTest.java View File

@@ -21,13 +21,15 @@ package org.sonar.core.platform;

import com.google.common.collect.ImmutableMap;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.assertj.core.data.MapEntry;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.updatecenter.common.Version;

import static org.assertj.core.api.Assertions.assertThat;
@@ -39,8 +41,11 @@ public class PluginLoaderTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();

@Rule
public LogTester logTester = new LogTester();

private PluginClassloaderFactory classloaderFactory = mock(PluginClassloaderFactory.class);
private PluginLoader loader = new PluginLoader(new FakePluginExploder(), classloaderFactory);
private PluginLoader underTest = new PluginLoader(new FakePluginExploder(), classloaderFactory);

@Test
public void define_classloader() throws Exception {
@@ -50,7 +55,7 @@ public class PluginLoaderTest {
.setMainClass("org.foo.FooPlugin")
.setMinimalSqVersion(Version.create("5.2"));

Collection<PluginClassLoaderDef> defs = loader.defineClassloaders(ImmutableMap.of("foo", info));
Collection<PluginClassLoaderDef> defs = underTest.defineClassloaders(ImmutableMap.of("foo", info));

assertThat(defs).hasSize(1);
PluginClassLoaderDef def = defs.iterator().next();
@@ -59,21 +64,6 @@ public class PluginLoaderTest {
assertThat(def.getFiles()).containsOnly(jarFile);
assertThat(def.getMainClassesByPluginKey()).containsOnly(MapEntry.entry("foo", "org.foo.FooPlugin"));
// TODO test mask - require change in sonar-classloader

// built with SQ 5.2+ -> does not need API compatibility mode
assertThat(def.isCompatibilityMode()).isFalse();
}

@Test
public void enable_compatibility_mode_if_plugin_is_built_before_5_2() throws Exception {
File jarFile = temp.newFile();
PluginInfo info = new PluginInfo("foo")
.setJarFile(jarFile)
.setMainClass("org.foo.FooPlugin")
.setMinimalSqVersion(Version.create("4.5.2"));

Collection<PluginClassLoaderDef> defs = loader.defineClassloaders(ImmutableMap.of("foo", info));
assertThat(defs.iterator().next().isCompatibilityMode()).isTrue();
}

/**
@@ -104,7 +94,7 @@ public class PluginLoaderTest {
.setBasePlugin("foo")
.setUseChildFirstClassLoader(true);

Collection<PluginClassLoaderDef> defs = loader.defineClassloaders(ImmutableMap.of(
Collection<PluginClassLoaderDef> defs = underTest.defineClassloaders(ImmutableMap.of(
base.getKey(), base, extension1.getKey(), extension1, extension2.getKey(), extension2));

assertThat(defs).hasSize(1);
@@ -120,22 +110,18 @@ public class PluginLoaderTest {
}

@Test
public void plugin_is_not_recognised_as_system_extension_if_key_is_governance_and_extends_another_plugin() throws IOException {
PluginInfo foo = createPluginInfo("foo");
PluginInfo governance = createPluginInfo("governance")
.setBasePlugin("foo");

Collection<PluginClassLoaderDef> defs = loader.defineClassloaders(ImmutableMap.of("foo", foo, "governance", governance));

assertThat(defs).extracting("compatibilityMode").containsOnly(false, false);
}

private PluginInfo createPluginInfo(String pluginKey) throws IOException {
public void log_warning_if_plugin_is_built_with_api_5_2_or_lower() throws Exception {
File jarFile = temp.newFile();
return new PluginInfo(pluginKey)
PluginInfo info = new PluginInfo("foo")
.setJarFile(jarFile)
.setMainClass("org.foo." + pluginKey + "Plugin")
.setMinimalSqVersion(Version.create("6.6"));
.setMainClass("org.foo.FooPlugin")
.setMinimalSqVersion(Version.create("4.5.2"));

Collection<PluginClassLoaderDef> defs = underTest.defineClassloaders(ImmutableMap.of("foo", info));
assertThat(defs).extracting(PluginClassLoaderDef::getBasePluginKey).containsExactly("foo");

List<String> warnings = logTester.logs(LoggerLevel.WARN);
assertThat(warnings).contains("API compatibility mode is no longer supported. In case of error, plugin foo [foo] should package its dependencies.");
}

/**

+ 1
- 0
sonar-duplications/build.gradle View File

@@ -8,6 +8,7 @@ dependencies {
// please keep list ordered

compile 'org.codehaus.sonar:sonar-channel'
compile project(':sonar-plugin-api')

compileOnly 'com.google.code.findbugs:jsr305'


+ 0
- 44
sonar-duplications/src/main/java/org/sonar/duplications/CodeFragment.java View File

@@ -1,44 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2018 SonarSource SA
* mailto:info 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.duplications;


/**
* TODO Enforce contracts of this interface in concrete classes by using preconditions, currently this leads to failures of tests.
*
* <p>This interface is not intended to be implemented by clients.</p>
*
* @since 2.14
*/
public interface CodeFragment {

/**
* Number of line where fragment starts.
* Numbering starts from 1.
*/
int getStartLine();

/**
* Number of line where fragment ends.
* Numbering starts from 1.
*/
int getEndLine();

}

+ 1
- 5
sonar-duplications/src/main/java/org/sonar/duplications/block/Block.java View File

@@ -19,13 +19,11 @@
*/
package org.sonar.duplications.block;

import org.sonar.duplications.CodeFragment;

/**
* Represents part of source code between two lines.
* If two blocks have the same {@link #getBlockHash() hash}, then we assume that there is a duplication in a code, which they represent.
*/
public final class Block implements CodeFragment {
public final class Block {

private final String resourceId;
private final ByteArray blockHash;
@@ -127,12 +125,10 @@ public final class Block implements CodeFragment {
return indexInFile;
}

@Override
public int getStartLine() {
return startLine;
}

@Override
public int getEndLine() {
return endLine;
}

+ 1
- 5
sonar-duplications/src/main/java/org/sonar/duplications/index/ClonePart.java View File

@@ -19,9 +19,7 @@
*/
package org.sonar.duplications.index;

import org.sonar.duplications.CodeFragment;

public class ClonePart implements CodeFragment {
public class ClonePart {

private final String resourceId;
private final int startUnit;
@@ -48,12 +46,10 @@ public class ClonePart implements CodeFragment {
return startUnit;
}

@Override
public int getStartLine() {
return startLine;
}

@Override
public int getEndLine() {
return endLine;
}

+ 1
- 2
sonar-duplications/src/main/java/org/sonar/duplications/internal/pmd/PmdBlockChunker.java View File

@@ -21,9 +21,8 @@ package org.sonar.duplications.internal.pmd;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.concurrent.Immutable;
import org.sonar.api.batch.sensor.cpd.internal.TokensLine;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.block.ByteArray;


+ 1
- 0
sonar-duplications/src/main/java/org/sonar/duplications/internal/pmd/TokenizerBridge.java View File

@@ -26,6 +26,7 @@ import net.sourceforge.pmd.cpd.SourceCode;
import net.sourceforge.pmd.cpd.TokenEntry;
import net.sourceforge.pmd.cpd.Tokenizer;
import net.sourceforge.pmd.cpd.Tokens;
import org.sonar.api.batch.sensor.cpd.internal.TokensLine;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.cpd.FileCodeLoaderWithoutCache;


+ 1
- 4
sonar-duplications/src/main/java/org/sonar/duplications/statement/Statement.java View File

@@ -21,10 +21,9 @@ package org.sonar.duplications.statement;

import java.util.List;
import javax.annotation.Nullable;
import org.sonar.duplications.CodeFragment;
import org.sonar.duplications.token.Token;

public class Statement implements CodeFragment {
public class Statement {

private final int startLine;
private final int endLine;
@@ -54,12 +53,10 @@ public class Statement implements CodeFragment {
this.endLine = tokens.get(tokens.size() - 1).getLine();
}

@Override
public int getStartLine() {
return startLine;
}

@Override
public int getEndLine() {
return endLine;
}

+ 3
- 3
sonar-duplications/src/test/java/org/sonar/duplications/internal/pmd/PmdBlockChunkerTest.java View File

@@ -19,13 +19,13 @@
*/
package org.sonar.duplications.internal.pmd;

import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.sonar.api.batch.sensor.cpd.internal.TokensLine;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.block.ByteArray;

import java.util.Arrays;
import java.util.List;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;


+ 1
- 0
sonar-duplications/src/test/java/org/sonar/duplications/internal/pmd/TokenizerBridgeTest.java View File

@@ -30,6 +30,7 @@ import net.sourceforge.pmd.cpd.Tokenizer;
import net.sourceforge.pmd.cpd.Tokens;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.batch.sensor.cpd.internal.TokensLine;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

+ 0
- 42
sonar-plugin-api-deps/build.gradle View File

@@ -1,42 +0,0 @@
sonarqube {
properties {
property 'sonar.projectName', "${projectTitle} :: Plugin API Dependencies"
}
}

apply plugin: 'com.github.johnrengelman.shadow'

dependencies {
// Versions must not be changed and overridden from root build.gradle (see dependencyManagement section).
// These are the versions defined in SQ 5.1
compile 'com.google.code.gson:gson:2.3.1'
compile 'com.google.guava:guava:10.0.1'
compile 'commons-beanutils:commons-beanutils:1.9.3'
compile 'commons-codec:commons-codec:1.8'
compile 'commons-collections:commons-collections:3.2.2'
compile 'org.apache.commons:commons-email:1.3.2'
compile 'commons-io:commons-io:2.4'
compile 'commons-lang:commons-lang:2.6'
compile('dom4j:dom4j:1.6.1') {
exclude group: 'xml-apis'
}
compile 'org.picocontainer:picocontainer:2.14.3'
compile 'org.slf4j:slf4j-api:1.7.10'
compile 'ch.qos.logback:logback-classic:1.1.2'
compile 'ch.qos.logback:logback-core:1.1.2'
compile('org.apache.maven:maven-core:3.0.5') {
exclude group: 'classworlds', module: 'classworlds'
exclude group: 'org.sonatype.sisu', module: 'sisu-guava'
}
compile 'org.apache.maven:maven-artifact:3.0.5'
compile('org.codehaus.sonar:sonar-squid:4.1') {
exclude group: 'org.codehaus.sonar', module: 'sonar-check-api'
}
compile('org.codehaus.sonar:sonar-java-api:5.1') {
exclude group: 'org.codehaus.sonar', module: 'sonar-deprecated'
exclude group: 'org.codehaus.sonar', module: 'sonar-plugin-api'
}
}

// This JAR is cached because used as a resource in sonar-core:
shadowJar.outputs.cacheIf { true }

+ 0
- 3
sonar-plugin-api/build.gradle View File

@@ -17,9 +17,6 @@ dependencies {

// shaded, but not relocated
compile project(':sonar-check-api')
compile(project(':sonar-duplications')) {
exclude group: 'org.slf4', module: 'slf4j-api'
}

shadow 'org.codehaus.staxmate:staxmate'
shadow 'org.codehaus.woodstox:stax2-api'

+ 1
- 2
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java View File

@@ -30,7 +30,6 @@ import org.sonar.api.batch.sensor.cpd.NewCpdTokens;
import org.sonar.api.batch.sensor.internal.DefaultStorable;
import org.sonar.api.batch.sensor.internal.SensorStorage;
import org.sonar.api.config.Configuration;
import org.sonar.duplications.internal.pmd.TokensLine;

import static com.google.common.base.Preconditions.checkState;
import static java.util.Collections.unmodifiableList;
@@ -39,7 +38,7 @@ import static java.util.Objects.requireNonNull;
public class DefaultCpdTokens extends DefaultStorable implements NewCpdTokens {

private final Configuration config;
private final ArrayList<TokensLine> result = new ArrayList<>();
private final List<TokensLine> result = new ArrayList<>();
private InputFile inputFile;
private int startLine = Integer.MIN_VALUE;
private int startIndex = 0;

sonar-duplications/src/main/java/org/sonar/duplications/internal/pmd/TokensLine.java → sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/TokensLine.java View File

@@ -17,14 +17,12 @@
* 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.duplications.internal.pmd;

import org.sonar.duplications.CodeFragment;
package org.sonar.api.batch.sensor.cpd.internal;

/**
* Immutable code fragment, which formed from tokens of one line.
*/
public class TokensLine implements CodeFragment {
public class TokensLine {

private final String value;

@@ -51,7 +49,6 @@ public class TokensLine implements CodeFragment {
return value;
}

@Override
public int getStartLine() {
return startLine;
}
@@ -59,7 +56,6 @@ public class TokensLine implements CodeFragment {
/**
* Same as {@link #getStartLine()}
*/
@Override
public int getEndLine() {
return startLine;
}

+ 1
- 1
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java View File

@@ -53,6 +53,7 @@ import org.sonar.api.batch.sensor.coverage.NewCoverage;
import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
import org.sonar.api.batch.sensor.cpd.NewCpdTokens;
import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens;
import org.sonar.api.batch.sensor.cpd.internal.TokensLine;
import org.sonar.api.batch.sensor.error.AnalysisError;
import org.sonar.api.batch.sensor.error.NewAnalysisError;
import org.sonar.api.batch.sensor.error.internal.DefaultAnalysisError;
@@ -80,7 +81,6 @@ import org.sonar.api.internal.SonarRuntimeImpl;
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;

import static java.util.Collections.unmodifiableMap;


+ 2
- 0
sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/IdentityProvider.java View File

@@ -19,6 +19,7 @@
*/
package org.sonar.api.server.authentication;

import org.sonar.api.ExtensionPoint;
import org.sonar.api.server.ServerSide;

/**
@@ -32,6 +33,7 @@ import org.sonar.api.server.ServerSide;
* @since 5.4
*/
@ServerSide
@ExtensionPoint
public interface IdentityProvider {

/**

+ 1
- 0
sonar-scanner-engine/build.gradle View File

@@ -30,6 +30,7 @@ dependencies {
compile project(':sonar-core')
compile project(':sonar-scanner-protocol')
compile project(':sonar-ws')
compile project(':sonar-duplications')
runtime project(path: ':sonar-plugin-api', configuration: 'shadow')
compileOnly project(path: ':sonar-plugin-api')


Loading…
Cancel
Save