aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-batch/src
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2015-08-06 14:38:53 +0200
committerDuarte Meneses <duarte.meneses@sonarsource.com>2015-08-12 16:12:50 +0200
commitda0e7d2eb596eeed136301cdaa38523ff8c86d54 (patch)
tree4e0dcbc4ea5ab12f48c9f807319cef76977b0d8f /sonar-batch/src
parent4dc9282453526c25504570caae011283b053ed98 (diff)
downloadsonarqube-da0e7d2eb596eeed136301cdaa38523ff8c86d54.tar.gz
sonarqube-da0e7d2eb596eeed136301cdaa38523ff8c86d54.zip
SONAR-6777 Project cache sync
Diffstat (limited to 'sonar-batch/src')
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java39
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalWSLoaderProvider.java (renamed from sonar-batch/src/main/java/org/sonar/batch/bootstrap/WSLoaderGlobalProvider.java)13
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/WSLoader.java78
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java15
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheStatus.java83
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java118
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/cache/ProjectSyncContainer.java84
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/cache/StrategyWSLoaderProvider.java45
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java10
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/mediumtest/FakePluginInstaller.java1
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java12
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesLoader.java5
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesProvider.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepositoryLoader.java (renamed from sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepository.java)33
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ProjectAnalysisMode.java5
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java25
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ProjectWSLoaderProvider.java15
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java8
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/GlobalWSLoaderProviderTest.java (renamed from sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderGlobalProviderTest.java)21
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTest.java65
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTestWithServer.java34
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheStatusTest.java71
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java8
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/DefaultServerLineHashesLoaderTest.java4
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/BatchMediumTester.java (renamed from sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java)10
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/cache/CacheSyncTest.java76
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/EmptyFileTest.java (renamed from sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/EmptyFileTest.java)2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java (renamed from sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/IssueModeAndReportsMediumTest.java)2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java41
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryLoaderTest.java (renamed from sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryTest.java)10
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/ProjectWSLoaderProviderTest.java (renamed from sonar-batch/src/test/java/org/sonar/batch/scan/WSLoaderProjectProviderTest.java)5
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java8
-rw-r--r--sonar-batch/src/test/resources/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest/sample_response.json2093
34 files changed, 2807 insertions, 236 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java
index 882aa173e48..feab390e969 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java
@@ -19,8 +19,10 @@
*/
package org.sonar.batch.bootstrap;
-import org.sonar.batch.rule.RulesLoader;
+import org.sonar.batch.scan.ProjectAnalysisMode;
+import org.sonar.batch.cache.ProjectSyncContainer;
+import org.sonar.batch.rule.RulesLoader;
import org.sonar.batch.rule.DefaultRulesLoader;
import org.sonar.batch.rule.RulesProvider;
@@ -33,17 +35,10 @@ import org.sonar.api.utils.Durations;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.UriReader;
import org.sonar.batch.index.CachesManager;
-import org.sonar.batch.issue.tracking.DefaultServerLineHashesLoader;
-import org.sonar.batch.issue.tracking.ServerLineHashesLoader;
import org.sonar.batch.platform.DefaultServer;
import org.sonar.batch.repository.DefaultGlobalRepositoriesLoader;
-import org.sonar.batch.repository.DefaultProjectRepositoriesLoader;
-import org.sonar.batch.repository.DefaultServerIssuesLoader;
import org.sonar.batch.repository.GlobalRepositoriesLoader;
import org.sonar.batch.repository.GlobalRepositoriesProvider;
-import org.sonar.batch.repository.ProjectRepositoriesLoader;
-import org.sonar.batch.repository.ServerIssuesLoader;
-import org.sonar.batch.repository.user.UserRepository;
import org.sonar.batch.scan.ProjectScanContainer;
import org.sonar.core.config.Logback;
import org.sonar.core.i18n.DefaultI18n;
@@ -99,25 +94,15 @@ public class GlobalContainer extends ComponentContainer {
UriReader.class,
new FileCacheProvider(),
new PersistentCacheProvider(),
- new WSLoaderGlobalProvider(),
+ new GlobalWSLoaderProvider(),
System2.INSTANCE,
DefaultI18n.class,
Durations.class,
RuleI18nManager.class,
- new GlobalRepositoriesProvider(),
- UserRepository.class);
+ new GlobalRepositoriesProvider());
addIfMissing(BatchPluginInstaller.class, PluginInstaller.class);
addIfMissing(DefaultRulesLoader.class, RulesLoader.class);
addIfMissing(DefaultGlobalRepositoriesLoader.class, GlobalRepositoriesLoader.class);
- addIfMissing(DefaultProjectRepositoriesLoader.class, ProjectRepositoriesLoader.class);
- addIfMissing(DefaultServerIssuesLoader.class, ServerIssuesLoader.class);
- addIfMissing(DefaultServerLineHashesLoader.class, ServerLineHashesLoader.class);
- }
-
- public void addIfMissing(Object object, Class<?> objectType) {
- if (getComponentByType(objectType) == null) {
- add(object);
- }
}
@Override
@@ -135,6 +120,20 @@ public class GlobalContainer extends ComponentContainer {
public void executeAnalysis(Map<String, String> analysisProperties, Object... components) {
AnalysisProperties props = new AnalysisProperties(analysisProperties, this.getComponentByType(BootstrapProperties.class).property(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
+ if (isIssuesMode(props)) {
+ new ProjectSyncContainer(this, props, false).execute();
+ }
new ProjectScanContainer(this, props, components).execute();
}
+
+ public void syncProject(Map<String, String> analysisProperties, boolean force) {
+ AnalysisProperties props = new AnalysisProperties(analysisProperties, this.getComponentByType(BootstrapProperties.class).property(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
+ new ProjectSyncContainer(this, props, force).execute();
+ }
+
+ private boolean isIssuesMode(AnalysisProperties props) {
+ ProjectAnalysisMode mode = new ProjectAnalysisMode(this.getComponentByType(BootstrapProperties.class), props);
+ return mode.isIssues();
+ }
+
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/WSLoaderGlobalProvider.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalWSLoaderProvider.java
index 71826511f1d..f89c4a3afed 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/WSLoaderGlobalProvider.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalWSLoaderProvider.java
@@ -22,23 +22,16 @@ package org.sonar.batch.bootstrap;
import org.picocontainer.injectors.ProviderAdapter;
import org.sonar.batch.bootstrap.WSLoader.LoadStrategy;
-import java.util.Map;
-
import org.sonar.home.cache.PersistentCache;
-public class WSLoaderGlobalProvider extends ProviderAdapter {
- private static final LoadStrategy DEFAULT_STRATEGY = LoadStrategy.SERVER_FIRST;
+public class GlobalWSLoaderProvider extends ProviderAdapter {
+ private static final LoadStrategy DEFAULT_STRATEGY = LoadStrategy.SERVER_ONLY;
private WSLoader wsLoader;
public WSLoader provide(BootstrapProperties props, GlobalMode mode, PersistentCache cache, ServerClient client) {
if (wsLoader == null) {
- wsLoader = new WSLoader(isCacheEnabled(props.properties(), mode), cache, client);
- wsLoader.setStrategy(DEFAULT_STRATEGY);
+ wsLoader = new WSLoader(DEFAULT_STRATEGY, cache, client);
}
return wsLoader;
}
-
- private static boolean isCacheEnabled(Map<String, String> props, GlobalMode mode) {
- return mode.isIssues();
- }
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java
index a205a01c81b..ef24962e6a8 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java
@@ -19,8 +19,6 @@
*/
package org.sonar.batch.bootstrap;
-import org.sonar.api.utils.HttpDownloader.HttpException;
-
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/WSLoader.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/WSLoader.java
index e6fb470395a..f231b473a1d 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/WSLoader.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/WSLoader.java
@@ -48,27 +48,21 @@ public class WSLoader {
}
public enum LoadStrategy {
- SERVER_FIRST, CACHE_FIRST;
+ SERVER_FIRST, CACHE_FIRST, SERVER_ONLY, CACHE_ONLY;
}
private LoadStrategy loadStrategy;
- private boolean cacheEnabled;
private ServerStatus serverStatus;
private ServerClient client;
private PersistentCache cache;
- public WSLoader(boolean cacheEnabled, PersistentCache cache, ServerClient client) {
- this.cacheEnabled = cacheEnabled;
- this.loadStrategy = CACHE_FIRST;
+ public WSLoader(LoadStrategy strategy, PersistentCache cache, ServerClient client) {
+ this.loadStrategy = strategy;
this.serverStatus = UNKNOWN;
this.cache = cache;
this.client = client;
}
- public WSLoader(PersistentCache cache, ServerClient client) {
- this(false, cache, client);
- }
-
@Nonnull
public WSLoaderResult<ByteSource> loadSource(String id) {
WSLoaderResult<byte[]> byteResult = load(id);
@@ -83,29 +77,23 @@ public class WSLoader {
@Nonnull
public WSLoaderResult<byte[]> load(String id) {
- if (loadStrategy == CACHE_FIRST) {
- return loadFromCacheFirst(id);
- } else {
- return loadFromServerFirst(id);
+ switch (loadStrategy) {
+ case CACHE_FIRST:
+ return loadFromCacheFirst(id, true);
+ case CACHE_ONLY:
+ return loadFromCacheFirst(id, false);
+ case SERVER_FIRST:
+ return loadFromServerFirst(id, true);
+ case SERVER_ONLY:
+ default:
+ return loadFromServerFirst(id, false);
}
}
- public void setStrategy(LoadStrategy strategy) {
- this.loadStrategy = strategy;
- }
-
public LoadStrategy getStrategy() {
return this.loadStrategy;
}
- public void setCacheEnabled(boolean enabled) {
- this.cacheEnabled = enabled;
- }
-
- public boolean isCacheEnabled() {
- return this.cacheEnabled;
- }
-
private void switchToOffline() {
LOG.debug("server not available - switching to offline mode");
serverStatus = NOT_ACCESSIBLE;
@@ -120,47 +108,47 @@ public class WSLoader {
}
private void updateCache(String id, byte[] value) {
- if (cacheEnabled) {
- try {
- cache.put(client.getURI(id).toString(), value);
- } catch (IOException e) {
- LOG.warn("Error saving to WS cache", e);
- }
+ try {
+ cache.put(client.getURI(id).toString(), value);
+ } catch (IOException e) {
+ LOG.warn("Error saving to WS cache", e);
}
}
@Nonnull
- private WSLoaderResult<byte[]> loadFromCacheFirst(String id) {
+ private WSLoaderResult<byte[]> loadFromCacheFirst(String id, boolean fallback) {
try {
return loadFromCache(id);
} catch (NotAvailableException cacheNotAvailable) {
- try {
- return loadFromServer(id);
- } catch (NotAvailableException serverNotAvailable) {
- throw new IllegalStateException(FAIL_MSG, serverNotAvailable.getCause());
+ if (fallback) {
+ try {
+ return loadFromServer(id);
+ } catch (NotAvailableException serverNotAvailable) {
+ throw new IllegalStateException(FAIL_MSG, serverNotAvailable.getCause());
+ }
}
+ throw new IllegalStateException(FAIL_MSG, cacheNotAvailable.getCause());
}
}
@Nonnull
- private WSLoaderResult<byte[]> loadFromServerFirst(String id) {
+ private WSLoaderResult<byte[]> loadFromServerFirst(String id, boolean fallback) {
try {
return loadFromServer(id);
} catch (NotAvailableException serverNotAvailable) {
- try {
- return loadFromCache(id);
- } catch (NotAvailableException cacheNotAvailable) {
- throw new IllegalStateException(FAIL_MSG, serverNotAvailable.getCause());
+ if (fallback) {
+ try {
+ return loadFromCache(id);
+ } catch (NotAvailableException cacheNotAvailable) {
+ throw new IllegalStateException(FAIL_MSG, serverNotAvailable.getCause());
+ }
}
+ throw new IllegalStateException(FAIL_MSG, serverNotAvailable.getCause());
}
}
@Nonnull
private WSLoaderResult<byte[]> loadFromCache(String id) throws NotAvailableException {
- if (!cacheEnabled) {
- throw new NotAvailableException("cache disabled");
- }
-
try {
byte[] result = cache.get(client.getURI(id).toString(), null);
if (result == null) {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java
index d28ff6cf2ac..12e564c5fcd 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java
@@ -19,11 +19,16 @@
*/
package org.sonar.batch.bootstrapper;
+import com.google.common.collect.ImmutableMap;
+
+import org.sonar.api.CoreProperties;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+
import java.util.Collections;
import java.util.List;
import java.util.Map;
+
import org.picocontainer.annotations.Nullable;
import org.sonar.batch.bootstrap.GlobalContainer;
@@ -121,6 +126,16 @@ public final class Batch {
}
/**
+ * @since 5.2
+ */
+ public Batch syncProject(String projectKey) {
+ checkStarted();
+ Map<String, String> props = ImmutableMap.of(CoreProperties.PROJECT_KEY_PROPERTY, projectKey);
+ bootstrapContainer.syncProject(props, true);
+ return this;
+ }
+
+ /**
* @since 4.4
*/
public synchronized void stop() {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheStatus.java b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheStatus.java
new file mode 100644
index 00000000000..d36e0b427ad
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheStatus.java
@@ -0,0 +1,83 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.cache;
+
+import org.sonar.batch.bootstrap.ServerClient;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Date;
+
+import org.sonar.home.cache.PersistentCache;
+
+public class ProjectCacheStatus {
+ private static final String STATUS_PREFIX = "cache-sync-status-";
+ private PersistentCache cache;
+ private ServerClient client;
+
+ public ProjectCacheStatus(PersistentCache cache, ServerClient client) {
+ this.cache = cache;
+ this.client = client;
+ }
+
+ public void save(String projectKey) {
+ Date now = new Date();
+
+ try {
+ ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
+ try (ObjectOutputStream objOutput = new ObjectOutputStream(byteOutput)) {
+ objOutput.writeObject(now);
+ }
+ cache.put(getKey(projectKey), byteOutput.toByteArray());
+ } catch (IOException e) {
+ throw new IllegalStateException("Failed to write cache sync status", e);
+ }
+ }
+
+ public void delete(String projectKey) {
+ try {
+ cache.put(getKey(projectKey), new byte[0]);
+ } catch (IOException e) {
+ throw new IllegalStateException("Failed to delete cache sync status", e);
+ }
+ }
+
+ public Date getSyncStatus(String projectKey) {
+ try {
+ byte[] status = cache.get(getKey(projectKey), null);
+ if (status == null || status.length == 0) {
+ return null;
+ }
+ ByteArrayInputStream byteInput = new ByteArrayInputStream(status);
+ try (ObjectInputStream objInput = new ObjectInputStream(byteInput)) {
+ return (Date) objInput.readObject();
+ }
+ } catch (IOException | ClassNotFoundException e) {
+ throw new IllegalStateException("Failed to read cache sync status", e);
+ }
+ }
+
+ private String getKey(String projectKey) {
+ return STATUS_PREFIX + client.getURL() + projectKey;
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java
new file mode 100644
index 00000000000..2854dce0985
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java
@@ -0,0 +1,118 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.cache;
+
+import org.sonar.api.batch.bootstrap.ProjectReactor;
+
+import org.sonar.batch.bootstrap.AnalysisProperties;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.batch.protocol.input.BatchInput.ServerIssue;
+import com.google.common.base.Function;
+import org.sonar.batch.protocol.input.FileData;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.sonar.batch.protocol.input.ProjectRepositories;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.batch.repository.user.UserRepositoryLoader;
+import org.sonar.batch.issue.tracking.ServerLineHashesLoader;
+import org.sonar.batch.repository.ServerIssuesLoader;
+import org.sonar.batch.repository.ProjectRepositoriesLoader;
+
+public class ProjectCacheSynchronizer {
+ private static final Logger LOG = Loggers.get(ProjectCacheSynchronizer.class);
+ private ProjectDefinition project;
+ private AnalysisProperties properties;
+ private ProjectRepositoriesLoader projectRepositoryLoader;
+ private ServerIssuesLoader issuesLoader;
+ private ServerLineHashesLoader lineHashesLoader;
+ private UserRepositoryLoader userRepository;
+ private ProjectCacheStatus cacheStatus;
+
+ public ProjectCacheSynchronizer(ProjectReactor project, ProjectRepositoriesLoader projectRepositoryLoader, AnalysisProperties properties,
+ ServerIssuesLoader issuesLoader, ServerLineHashesLoader lineHashesLoader, UserRepositoryLoader userRepository, ProjectCacheStatus cacheStatus) {
+ this.project = project.getRoot();
+ this.projectRepositoryLoader = projectRepositoryLoader;
+ this.properties = properties;
+ this.issuesLoader = issuesLoader;
+ this.lineHashesLoader = lineHashesLoader;
+ this.userRepository = userRepository;
+ this.cacheStatus = cacheStatus;
+ }
+
+ public void load(boolean force) {
+ Date lastSync = cacheStatus.getSyncStatus(project.getKeyWithBranch());
+
+ if (lastSync != null) {
+ LOG.debug("Found project [" + project.getKeyWithBranch() + " ] cache [" + lastSync + "]");
+
+ if (!force) {
+ return;
+ }
+ }
+
+ cacheStatus.delete(project.getKeyWithBranch());
+ ProjectRepositories projectRepo = projectRepositoryLoader.load(project, properties);
+
+ if (projectRepo.lastAnalysisDate() == null) {
+ return;
+ }
+
+ IssueAccumulator consumer = new IssueAccumulator();
+ issuesLoader.load(project.getKeyWithBranch(), consumer, false);
+
+ for (String login : consumer.loginSet) {
+ userRepository.load(login);
+ }
+
+ loadLineHashes(projectRepo.fileDataByModuleAndPath());
+ cacheStatus.save(project.getKeyWithBranch());
+ }
+
+ private String getComponentKey(String moduleKey, String filePath) {
+ return moduleKey + ":" + filePath;
+ }
+
+ private void loadLineHashes(Map<String, Map<String, FileData>> fileDataByModuleAndPath) {
+ for (Entry<String, Map<String, FileData>> e1 : fileDataByModuleAndPath.entrySet()) {
+ String moduleKey = e1.getKey();
+
+ for (Entry<String, FileData> e2 : e1.getValue().entrySet()) {
+ String filePath = e2.getKey();
+ lineHashesLoader.getLineHashes(getComponentKey(moduleKey, filePath));
+ }
+ }
+ }
+
+ private static class IssueAccumulator implements Function<ServerIssue, Void> {
+ Set<String> loginSet = new HashSet<>();
+
+ @Override
+ public Void apply(ServerIssue input) {
+ loginSet.add(input.getAssigneeLogin());
+ return null;
+ }
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectSyncContainer.java b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectSyncContainer.java
new file mode 100644
index 00000000000..4be7ab575f4
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectSyncContainer.java
@@ -0,0 +1,84 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.cache;
+
+import org.sonar.batch.scan.ProjectAnalysisMode;
+
+import org.apache.commons.lang.StringUtils;
+import org.sonar.batch.bootstrap.WSLoader.LoadStrategy;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.bootstrap.ProjectReactor;
+import org.sonar.batch.bootstrap.AnalysisProperties;
+import org.sonar.batch.repository.user.UserRepositoryLoader;
+import org.sonar.batch.issue.tracking.ServerLineHashesLoader;
+import org.sonar.batch.repository.DefaultProjectRepositoriesLoader;
+import org.sonar.batch.repository.DefaultServerIssuesLoader;
+import org.sonar.batch.repository.ProjectRepositoriesLoader;
+import org.sonar.batch.repository.ServerIssuesLoader;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.batch.issue.tracking.DefaultServerLineHashesLoader;
+import org.sonar.core.platform.ComponentContainer;
+
+public class ProjectSyncContainer extends ComponentContainer {
+ private final boolean force;
+ private final AnalysisProperties properties;
+
+ public ProjectSyncContainer(ComponentContainer globalContainer, AnalysisProperties analysisProperties, boolean force) {
+ super(globalContainer);
+ this.properties = analysisProperties;
+ this.force = force;
+ }
+
+ @Override
+ protected void doBeforeStart() {
+ ProjectReactor projectReactor = createSimpleProjectReactor();
+ add(projectReactor);
+ addComponents();
+ }
+
+ private ProjectReactor createSimpleProjectReactor() {
+ ProjectDefinition rootProjDefinition = ProjectDefinition.create();
+ String projectKey = properties.property(CoreProperties.PROJECT_KEY_PROPERTY);
+ if (StringUtils.isEmpty(projectKey)) {
+ throw new IllegalStateException("Missing mandatory property: " + CoreProperties.PROJECT_KEY_PROPERTY);
+ }
+ rootProjDefinition.setKey(projectKey);
+ return new ProjectReactor(rootProjDefinition);
+ }
+
+ @Override
+ public void doAfterStart() {
+ getComponentByType(ProjectCacheSynchronizer.class).load(force);
+ }
+
+ private void addComponents() {
+ add(new StrategyWSLoaderProvider(LoadStrategy.SERVER_FIRST),
+ properties,
+ ProjectAnalysisMode.class,
+ ProjectCacheStatus.class,
+ ProjectCacheSynchronizer.class,
+ UserRepositoryLoader.class);
+
+ addIfMissing(DefaultProjectRepositoriesLoader.class, ProjectRepositoriesLoader.class);
+ addIfMissing(DefaultServerIssuesLoader.class, ServerIssuesLoader.class);
+ addIfMissing(DefaultServerLineHashesLoader.class, ServerLineHashesLoader.class);
+ }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/StrategyWSLoaderProvider.java b/sonar-batch/src/main/java/org/sonar/batch/cache/StrategyWSLoaderProvider.java
new file mode 100644
index 00000000000..9ebfd52034a
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/cache/StrategyWSLoaderProvider.java
@@ -0,0 +1,45 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.cache;
+
+import org.picocontainer.injectors.ProviderAdapter;
+
+import org.sonar.batch.bootstrap.BootstrapProperties;
+import org.sonar.batch.bootstrap.GlobalMode;
+import org.sonar.batch.bootstrap.ServerClient;
+import org.sonar.batch.bootstrap.WSLoader;
+import org.sonar.batch.bootstrap.WSLoader.LoadStrategy;
+import org.sonar.home.cache.PersistentCache;
+
+public class StrategyWSLoaderProvider extends ProviderAdapter {
+ private final LoadStrategy strategy;
+ private WSLoader wsLoader;
+
+ public StrategyWSLoaderProvider(LoadStrategy strategy) {
+ this.strategy = strategy;
+ }
+
+ public WSLoader provide(BootstrapProperties props, GlobalMode mode, PersistentCache cache, ServerClient client) {
+ if (wsLoader == null) {
+ wsLoader = new WSLoader(strategy, cache, client);
+ }
+ return wsLoader;
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java
index d4284f44e47..9973b50f612 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java
@@ -31,21 +31,21 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import org.sonar.batch.repository.user.UserRepository;
+import org.sonar.batch.repository.user.UserRepositoryLoader;
import org.sonar.batch.bootstrapper.IssueListener;
import org.sonar.core.issue.DefaultIssue;
public class DefaultIssueCallback implements IssueCallback {
private final IssueCache issues;
private final IssueListener listener;
- private final UserRepository userRepository;
+ private final UserRepositoryLoader userRepository;
private final Rules rules;
private Set<String> userLoginNames = new HashSet<>();
private Map<String, String> userMap = new HashMap<>();
private Set<RuleKey> ruleKeys = new HashSet<>();
- public DefaultIssueCallback(IssueCache issues, IssueListener listener, UserRepository userRepository, Rules rules) {
+ public DefaultIssueCallback(IssueCache issues, IssueListener listener, UserRepositoryLoader userRepository, Rules rules) {
this.issues = issues;
this.listener = listener;
this.userRepository = userRepository;
@@ -55,7 +55,7 @@ public class DefaultIssueCallback implements IssueCallback {
/**
* If no listener exists, this constructor will be used by pico.
*/
- public DefaultIssueCallback(IssueCache issues, UserRepository userRepository, Rules rules) {
+ public DefaultIssueCallback(IssueCache issues, UserRepositoryLoader userRepository, Rules rules) {
this(issues, null, userRepository, rules);
}
@@ -104,7 +104,7 @@ public class DefaultIssueCallback implements IssueCallback {
}
private void getUsers() {
- Collection<User> users = userRepository.loadFromWs(new ArrayList<>(userLoginNames));
+ Collection<User> users = userRepository.load(new ArrayList<>(userLoginNames));
for (User user : users) {
userMap.put(user.getLogin(), user.getName());
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/FakePluginInstaller.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/FakePluginInstaller.java
index cbd837c66c9..b77f97795e9 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/FakePluginInstaller.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/FakePluginInstaller.java
@@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.Map;
public class FakePluginInstaller implements PluginInstaller {
+ public static final String MEDIUM_TEST_ENABLED = "sonar.mediumTest.enabled";
private final Map<String, PluginInfo> infosByKeys = new HashMap<>();
private final Map<String, Plugin> instancesByKeys = new HashMap<>();
diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java
index 8a5bfe64152..d358861b21d 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java
@@ -19,12 +19,12 @@
*/
package org.sonar.batch.repository;
-import org.sonar.batch.bootstrap.AbstractServerLoader;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.batch.bootstrap.AbstractServerLoader;
import org.sonar.batch.bootstrap.WSLoaderResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.utils.MessageException;
import org.sonar.batch.bootstrap.AnalysisProperties;
import org.sonar.batch.bootstrap.GlobalMode;
@@ -47,8 +47,8 @@ public class DefaultProjectRepositoriesLoader extends AbstractServerLoader imple
}
@Override
- public ProjectRepositories load(ProjectReactor reactor, AnalysisProperties taskProperties) {
- String projectKey = reactor.getRoot().getKeyWithBranch();
+ public ProjectRepositories load(ProjectDefinition projectDefinition, AnalysisProperties taskProperties) {
+ String projectKey = projectDefinition.getKeyWithBranch();
String url = BATCH_PROJECT_URL + "?key=" + BatchUtils.encodeForUrl(projectKey);
if (taskProperties.properties().containsKey(ModuleQProfiles.SONAR_PROFILE_PROP)) {
LOG.warn("Ability to set quality profile from command line using '" + ModuleQProfiles.SONAR_PROFILE_PROP
@@ -57,7 +57,7 @@ public class DefaultProjectRepositoriesLoader extends AbstractServerLoader imple
}
url += "&preview=" + globalMode.isIssues();
ProjectRepositories projectRepositories = ProjectRepositories.fromJson(load(url));
- validateProjectRepositories(projectRepositories, reactor.getRoot().getKey());
+ validateProjectRepositories(projectRepositories);
return projectRepositories;
}
@@ -67,7 +67,7 @@ public class DefaultProjectRepositoriesLoader extends AbstractServerLoader imple
return result.get();
}
- private static void validateProjectRepositories(ProjectRepositories projectRepositories, String projectKey) {
+ private static void validateProjectRepositories(ProjectRepositories projectRepositories) {
if (projectRepositories.qProfiles().isEmpty()) {
throw MessageException.of("No quality profiles has been found this project, you probably don't have any language plugin suitable for this analysis.");
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesLoader.java
index 1dbff7350b4..dfb3b741202 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesLoader.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesLoader.java
@@ -19,13 +19,14 @@
*/
package org.sonar.batch.repository;
-import org.sonar.api.batch.bootstrap.ProjectReactor;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+
import org.sonar.batch.bootstrap.AnalysisProperties;
import org.sonar.batch.protocol.input.ProjectRepositories;
public interface ProjectRepositoriesLoader {
- ProjectRepositories load(ProjectReactor reactor, AnalysisProperties taskProperties);
+ ProjectRepositories load(ProjectDefinition projectDefinition, AnalysisProperties taskProperties);
boolean loadedFromCache();
diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesProvider.java b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesProvider.java
index aa79cc382af..27be9a46b80 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesProvider.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesProvider.java
@@ -38,7 +38,7 @@ public class ProjectRepositoriesProvider extends ProviderAdapter {
public ProjectRepositories provide(ProjectRepositoriesLoader loader, ProjectReactor reactor, AnalysisProperties taskProps, AnalysisMode analysisMode) {
if (projectReferentials == null) {
Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG);
- projectReferentials = loader.load(reactor, taskProps);
+ projectReferentials = loader.load(reactor.getRoot(), taskProps);
if (loader.loadedFromCache()) {
profiler.stopInfo(LOG_MSG + " (done from cache)");
diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepository.java b/sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepositoryLoader.java
index a0e4c781290..43d2383b50d 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepository.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepositoryLoader.java
@@ -39,27 +39,38 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
-public class UserRepository {
- private static final Logger LOG = Loggers.get(UserRepository.class);
+public class UserRepositoryLoader {
+ private static final Logger LOG = Loggers.get(UserRepositoryLoader.class);
private final WSLoader wsLoader;
- public UserRepository(WSLoader wsLoader) {
+ public UserRepositoryLoader(WSLoader wsLoader) {
this.wsLoader = wsLoader;
}
-
- public Collection<BatchInput.User> loadFromWs(List<String> userLogins) {
+
+ public BatchInput.User load(String userLogin) {
+ ByteSource byteSource = loadUsers(new UserEncodingFunction().apply(userLogin));
+ return parseUser(byteSource);
+ }
+
+ public Collection<BatchInput.User> load(List<String> userLogins) {
if (userLogins.isEmpty()) {
return Collections.emptyList();
}
+ ByteSource byteSource = loadUsers(Joiner.on(',').join(Lists.transform(userLogins, new UserEncodingFunction())));
+
+ return parseUsers(byteSource);
+ }
+
+ private ByteSource loadUsers(String loginsQuery) {
Profiler profiler = Profiler.create(LOG).startDebug("Load user repository");
- WSLoaderResult<ByteSource> result = wsLoader.loadSource("/batch/users?logins=" + Joiner.on(',').join(Lists.transform(userLogins, new UserEncodingFunction())));
+ WSLoaderResult<ByteSource> result = wsLoader.loadSource("/batch/users?logins=" + loginsQuery);
if (result.isFromCache()) {
profiler.stopInfo("Load user repository (done from cache)");
} else {
profiler.stopInfo();
}
- return parseUsers(result.get());
+ return result.get();
}
private static class UserEncodingFunction implements Function<String, String> {
@@ -69,6 +80,14 @@ public class UserRepository {
}
}
+ private static BatchInput.User parseUser(ByteSource input) {
+ try (InputStream is = input.openStream()) {
+ return BatchInput.User.parseFrom(is);
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to get user details from server", e);
+ }
+ }
+
private static Collection<BatchInput.User> parseUsers(ByteSource input) {
List<BatchInput.User> users = new ArrayList<>();
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectAnalysisMode.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectAnalysisMode.java
index 864bc9ccbda..4c66441218b 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectAnalysisMode.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectAnalysisMode.java
@@ -19,6 +19,8 @@
*/
package org.sonar.batch.scan;
+import org.sonar.batch.mediumtest.FakePluginInstaller;
+
import org.apache.commons.lang.StringUtils;
import org.sonar.batch.bootstrap.BootstrapProperties;
import org.sonar.batch.bootstrap.AnalysisProperties;
@@ -26,7 +28,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.AnalysisMode;
-import org.sonar.batch.mediumtest.BatchMediumTester;
import java.util.Map;
@@ -81,7 +82,7 @@ public class ProjectAnalysisMode implements AnalysisMode {
validate(mode);
preview = CoreProperties.ANALYSIS_MODE_PREVIEW.equals(mode);
issues = CoreProperties.ANALYSIS_MODE_ISSUES.equals(mode);
- mediumTestMode = "true".equals(getPropertyWithFallback(analysisProps, globalProps, BatchMediumTester.MEDIUM_TEST_ENABLED));
+ mediumTestMode = "true".equals(getPropertyWithFallback(analysisProps, globalProps, FakePluginInstaller.MEDIUM_TEST_ENABLED));
if (preview) {
LOG.info("Preview mode");
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
index 28367ee042c..6ab4474292a 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
@@ -19,8 +19,16 @@
*/
package org.sonar.batch.scan;
+import org.sonar.batch.cache.ProjectSyncContainer;
+
+import org.sonar.batch.repository.user.UserRepositoryLoader;
+import org.sonar.batch.issue.tracking.DefaultServerLineHashesLoader;
+import org.sonar.batch.issue.tracking.ServerLineHashesLoader;
+import org.sonar.batch.repository.DefaultProjectRepositoriesLoader;
+import org.sonar.batch.repository.DefaultServerIssuesLoader;
+import org.sonar.batch.repository.ProjectRepositoriesLoader;
+import org.sonar.batch.repository.ServerIssuesLoader;
import org.sonar.batch.issue.DefaultIssueCallback;
-
import com.google.common.annotations.VisibleForTesting;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.InstantiationStrategy;
@@ -118,6 +126,13 @@ public class ProjectScanContainer extends ComponentContainer {
return env != null && "SonarRunner".equals(env.getKey());
}
+ private void doProjectSync() {
+ ProjectAnalysisMode mode = getComponentByType(ProjectAnalysisMode.class);
+ if (mode.isIssues()) {
+ new ProjectSyncContainer(getParent(), props, false).execute();
+ }
+ }
+
private void addBatchComponents() {
add(
props,
@@ -194,7 +209,12 @@ public class ProjectScanContainer extends ComponentContainer {
SourcePublisher.class,
TestExecutionAndCoveragePublisher.class,
- ScanTaskObservers.class);
+ ScanTaskObservers.class,
+ UserRepositoryLoader.class);
+
+ addIfMissing(DefaultProjectRepositoriesLoader.class, ProjectRepositoriesLoader.class);
+ addIfMissing(DefaultServerIssuesLoader.class, ServerIssuesLoader.class);
+ addIfMissing(DefaultServerLineHashesLoader.class, ServerLineHashesLoader.class);
}
private void addBatchExtensions() {
@@ -230,4 +250,5 @@ public class ProjectScanContainer extends ComponentContainer {
&& ExtensionUtils.isInstantiationStrategy(extension, InstantiationStrategy.PER_BATCH);
}
}
+
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectWSLoaderProvider.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectWSLoaderProvider.java
index 596c6df3069..7af51a25cc8 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectWSLoaderProvider.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectWSLoaderProvider.java
@@ -31,29 +31,22 @@ import org.sonar.api.batch.AnalysisMode;
import org.sonar.batch.bootstrap.WSLoader.LoadStrategy;
public class ProjectWSLoaderProvider extends ProviderAdapter {
- private static final String OPTIMIZE_STRING_PROP = "sonar.optimizeForSpeed";
private WSLoader wsLoader;
public WSLoader provide(AnalysisProperties props, AnalysisMode mode, PersistentCache cache, ServerClient client) {
if (wsLoader == null) {
// recreate cache directory if needed for this analysis
cache.reconfigure();
- wsLoader = new WSLoader(isCacheEnabled(props.properties(), mode), cache, client);
- wsLoader.setStrategy(getStrategy(props.properties(), mode));
+ wsLoader = new WSLoader(getStrategy(props.properties(), mode), cache, client);
}
return wsLoader;
}
private static LoadStrategy getStrategy(Map<String, String> props, AnalysisMode mode) {
- String optimizeForSpeed = props.get(OPTIMIZE_STRING_PROP);
- if (mode.isIssues() && "true".equals(optimizeForSpeed)) {
- return LoadStrategy.CACHE_FIRST;
+ if (mode.isIssues()) {
+ return LoadStrategy.CACHE_ONLY;
}
- return LoadStrategy.SERVER_FIRST;
- }
-
- private static boolean isCacheEnabled(Map<String, String> props, AnalysisMode mode) {
- return mode.isIssues();
+ return LoadStrategy.SERVER_ONLY;
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java
index 22c02ff6e42..30c56af99d7 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java
@@ -51,7 +51,7 @@ import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.batch.issue.IssueCache;
import org.sonar.batch.protocol.input.BatchInput;
-import org.sonar.batch.repository.user.UserRepository;
+import org.sonar.batch.repository.user.UserRepositoryLoader;
import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.core.issue.DefaultIssue;
@@ -74,10 +74,10 @@ public class JSONReport implements Reporter {
private final IssueCache issueCache;
private final InputPathCache fileCache;
private final Project rootModule;
- private final UserRepository userRepository;
+ private final UserRepositoryLoader userRepository;
public JSONReport(Settings settings, FileSystem fileSystem, Server server, Rules rules, IssueCache issueCache,
- Project rootModule, InputPathCache fileCache, UserRepository userRepository) {
+ Project rootModule, InputPathCache fileCache, UserRepositoryLoader userRepository) {
this.settings = settings;
this.fileSystem = fileSystem;
this.server = server;
@@ -120,7 +120,7 @@ public class JSONReport implements Reporter {
writeJsonIssues(json, ruleKeys, userLogins);
writeJsonComponents(json);
writeJsonRules(json, ruleKeys);
- Collection<BatchInput.User> users = userRepository.loadFromWs(new ArrayList<>(userLogins));
+ Collection<BatchInput.User> users = userRepository.load(new ArrayList<>(userLogins));
writeUsers(json, users);
json.endObject().close();
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderGlobalProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/GlobalWSLoaderProviderTest.java
index 81a5fdb563f..1ae0c36ab2f 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderGlobalProviderTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/GlobalWSLoaderProviderTest.java
@@ -24,8 +24,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.util.HashMap;
import java.util.Map;
-import static org.mockito.Mockito.when;
-
import org.sonar.batch.bootstrap.WSLoader.LoadStrategy;
import org.junit.Test;
import org.junit.Before;
@@ -33,7 +31,7 @@ import org.sonar.home.cache.PersistentCache;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-public class WSLoaderGlobalProviderTest {
+public class GlobalWSLoaderProviderTest {
@Mock
private PersistentCache cache;
@@ -43,14 +41,14 @@ public class WSLoaderGlobalProviderTest {
@Mock
private GlobalMode mode;
- private WSLoaderGlobalProvider loaderProvider;
+ private GlobalWSLoaderProvider loaderProvider;
private Map<String, String> propMap;
private BootstrapProperties props;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- loaderProvider = new WSLoaderGlobalProvider();
+ loaderProvider = new GlobalWSLoaderProvider();
}
@Test
@@ -59,18 +57,7 @@ public class WSLoaderGlobalProviderTest {
props = new BootstrapProperties(propMap);
WSLoader wsLoader = loaderProvider.provide(props, mode, cache, client);
- assertThat(wsLoader.getStrategy()).isEqualTo(LoadStrategy.SERVER_FIRST);
- assertThat(wsLoader.isCacheEnabled()).isEqualTo(false);
+ assertThat(wsLoader.getStrategy()).isEqualTo(LoadStrategy.SERVER_ONLY);
}
- @Test
- public void testOffline() {
- propMap = new HashMap<>();
- propMap.put("sonar.enableOffline", "true");
- when(mode.isIssues()).thenReturn(true);
- props = new BootstrapProperties(propMap);
-
- WSLoader wsLoader = loaderProvider.provide(props, mode, cache, client);
- assertThat(wsLoader.isCacheEnabled()).isEqualTo(true);
- }
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTest.java
index 31c70e85d4b..781c1ad255c 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTest.java
@@ -70,10 +70,9 @@ public class WSLoaderTest {
}
@Test
- public void dont_retry_server() throws IOException {
- when(client.load(anyString(), anyString(), anyBoolean(), anyInt(), anyInt())).thenThrow(new IllegalStateException());
- WSLoader loader = new WSLoader(true, cache, client);
- loader.setStrategy(LoadStrategy.SERVER_FIRST);
+ public void dont_retry_server_offline() throws IOException {
+ turnServerOffline();
+ WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client);
assertResult(loader.loadString(ID), cacheValue, true);
assertResult(loader.loadString(ID), cacheValue, true);
@@ -86,8 +85,7 @@ public class WSLoaderTest {
@Test
public void test_cache_strategy_fallback() throws IOException {
when(cache.get(ID, null)).thenReturn(null);
- WSLoader loader = new WSLoader(true, cache, client);
- loader.setStrategy(LoadStrategy.CACHE_FIRST);
+ WSLoader loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client);
assertResult(loader.load(ID), serverValue.getBytes(), false);
@@ -98,9 +96,8 @@ public class WSLoaderTest {
@Test
public void test_server_strategy_fallback() throws IOException {
- when(client.load(anyString(), anyString(), anyBoolean(), anyInt(), anyInt())).thenThrow(new IllegalStateException());
- WSLoader loader = new WSLoader(true, cache, client);
- loader.setStrategy(LoadStrategy.SERVER_FIRST);
+ turnServerOffline();
+ WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client);
assertResult(loader.loadString(ID), cacheValue, true);
@@ -111,20 +108,16 @@ public class WSLoaderTest {
@Test
public void test_put_cache() throws IOException {
- WSLoader loader = new WSLoader(true, cache, client);
- loader.setStrategy(LoadStrategy.SERVER_FIRST);
+ WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client);
loader.load(ID);
verify(cache).put(ID, serverValue.getBytes());
}
@Test(expected = NullPointerException.class)
public void test_throw_cache_exception_fallback() throws IOException {
- when(client.load(anyString(), anyString(), anyBoolean(), anyInt(), anyInt())).thenThrow(new IllegalStateException());
+ turnServerOffline();
when(cache.get(ID, null)).thenThrow(new NullPointerException());
-
- WSLoader loader = new WSLoader(true, cache, client);
- loader.setStrategy(LoadStrategy.SERVER_FIRST);
-
+ WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client);
loader.load(ID);
}
@@ -132,9 +125,7 @@ public class WSLoaderTest {
public void test_throw_cache_exception() throws IOException {
when(cache.get(ID, null)).thenThrow(new IllegalStateException());
- WSLoader loader = new WSLoader(true, cache, client);
- loader.setStrategy(LoadStrategy.CACHE_FIRST);
-
+ WSLoader loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client);
loader.load(ID);
}
@@ -145,8 +136,7 @@ public class WSLoaderTest {
when(client.load(anyString(), anyString(), anyBoolean(), anyInt(), anyInt())).thenThrow(wrapperException);
- WSLoader loader = new WSLoader(true, cache, client);
- loader.setStrategy(LoadStrategy.SERVER_FIRST);
+ WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client);
try {
loader.load(ID);
@@ -158,23 +148,8 @@ public class WSLoaderTest {
}
@Test
- public void test_change_strategy() throws IOException {
- WSLoader loader = new WSLoader(true, cache, client);
- loader.setStrategy(LoadStrategy.CACHE_FIRST);
- test_cache_strategy_fallback();
- }
-
- @Test
- public void test_enable_cache() throws IOException {
- WSLoader loader = new WSLoader(true, cache, client);
- loader.setCacheEnabled(false);
- test_cache_disabled();
- }
-
- @Test
public void test_server_strategy() throws IOException {
- WSLoader loader = new WSLoader(true, cache, client);
- loader.setStrategy(LoadStrategy.SERVER_FIRST);
+ WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client);
assertResult(loader.load(ID), serverValue.getBytes(), false);
// should not fetch from cache
@@ -182,18 +157,16 @@ public class WSLoaderTest {
verifyNoMoreInteractions(cache);
}
- @Test
- public void test_cache_disabled() throws IOException {
- WSLoader loader = new WSLoader(cache, client);
+ @Test(expected = IllegalStateException.class)
+ public void test_server_only() throws IOException {
+ turnServerOffline();
+ WSLoader loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client);
loader.load(ID);
-
- // should not even put
- verifyNoMoreInteractions(cache);
}
@Test
public void test_string() {
- WSLoader loader = new WSLoader(cache, client);
+ WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client);
assertResult(loader.loadString(ID), serverValue, false);
}
@@ -202,4 +175,8 @@ public class WSLoaderTest {
assertThat(result.get()).isEqualTo(expected);
assertThat(result.isFromCache()).isEqualTo(fromCache);
}
+
+ private void turnServerOffline() {
+ when(client.load(anyString(), anyString(), anyBoolean(), anyInt(), anyInt())).thenThrow(new IllegalStateException());
+ }
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTestWithServer.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTestWithServer.java
index b99d851d321..b6582883ebc 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTestWithServer.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTestWithServer.java
@@ -52,7 +52,6 @@ public class WSLoaderTestWithServer {
client = new ServerClient(bootstrapProps, new EnvironmentInformation("Junit", "4"));
cache = new PersistentCache(temp.getRoot().toPath(), 1000 * 60, new Slf4jLogger(), null);
- loader = new WSLoader(cache, client);
}
@After
@@ -63,50 +62,41 @@ public class WSLoaderTestWithServer {
}
@Test
- public void testServer() {
- loader.setCacheEnabled(false);
- loader.setStrategy(LoadStrategy.SERVER_FIRST);
- server.setMockResponseData(RESPONSE_STRING);
- assertThat(loader.loadString("/foo")).isEqualTo(RESPONSE_STRING);
- }
+ public void testCacheOnly() {
+ loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client);
+ makeRequests();
- @Test
- public void testCacheDisabled() {
- loader.setCacheEnabled(false);
- loader.setStrategy(LoadStrategy.CACHE_FIRST);
+ loader = new WSLoader(LoadStrategy.CACHE_ONLY, cache, client);
makeRequests();
assertThat(server.getNumberRequests()).isEqualTo(3);
}
@Test
- public void testCacheEnabled() {
- loader.setCacheEnabled(true);
- loader.setStrategy(LoadStrategy.CACHE_FIRST);
+ public void testCacheFirst() {
+ loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client);
makeRequests();
assertThat(server.getNumberRequests()).isEqualTo(1);
}
@Test
- public void testServerStrategy() {
- loader.setCacheEnabled(true);
- loader.setStrategy(LoadStrategy.SERVER_FIRST);
+ public void testServerFirst() {
+ loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client);
makeRequests();
assertThat(server.getNumberRequests()).isEqualTo(3);
}
@Test
public void testCacheStrategyDisabled() {
- loader.setCacheEnabled(false);
- loader.setStrategy(LoadStrategy.CACHE_FIRST);
+ loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client);
makeRequests();
assertThat(server.getNumberRequests()).isEqualTo(3);
}
private void makeRequests() {
server.setMockResponseData(RESPONSE_STRING);
- assertThat(loader.loadString("/foo")).isEqualTo(RESPONSE_STRING);
- assertThat(loader.loadString("/foo")).isEqualTo(RESPONSE_STRING);
- assertThat(loader.loadString("/foo")).isEqualTo(RESPONSE_STRING);
+ assertThat(loader.loadString("/foo").get()).isEqualTo(RESPONSE_STRING);
+ assertThat(loader.loadString("/foo").get()).isEqualTo(RESPONSE_STRING);
+ assertThat(loader.loadString("/foo").get()).isEqualTo(RESPONSE_STRING);
}
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheStatusTest.java b/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheStatusTest.java
new file mode 100644
index 00000000000..2b6c4491f62
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheStatusTest.java
@@ -0,0 +1,71 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.cache;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Date;
+
+import org.junit.Test;
+import org.sonar.home.cache.Logger;
+import org.junit.rules.TemporaryFolder;
+import org.junit.Rule;
+import org.junit.Before;
+import org.sonar.batch.bootstrap.ServerClient;
+import org.sonar.home.cache.PersistentCache;
+
+public class ProjectCacheStatusTest {
+ private static final String PROJ_KEY = "project1";
+ @Rule
+ public TemporaryFolder tmp = new TemporaryFolder();
+
+ ProjectCacheStatus cacheStatus;
+ PersistentCache cache;
+ ServerClient client;
+
+ @Before
+ public void setUp() {
+ cache = new PersistentCache(tmp.getRoot().toPath(), Long.MAX_VALUE, mock(Logger.class), null);
+ client = mock(ServerClient.class);
+ when(client.getURL()).thenReturn("localhost");
+ cacheStatus = new ProjectCacheStatus(cache, client);
+ }
+
+ @Test
+ public void testSave() {
+ cacheStatus.save(PROJ_KEY);
+ assertThat(cacheStatus.getSyncStatus(PROJ_KEY)).isNotNull();
+ assertThat(age(cacheStatus.getSyncStatus(PROJ_KEY))).isLessThan(2000);
+ assertThat(cacheStatus.getSyncStatus(PROJ_KEY+"1")).isNull();
+ }
+
+ @Test
+ public void testDelete() {
+ cacheStatus.save(PROJ_KEY);
+ cacheStatus.delete(PROJ_KEY);
+ assertThat(cacheStatus.getSyncStatus(PROJ_KEY)).isNull();
+ }
+
+ private long age(Date date) {
+ return (new Date().getTime()) - date.getTime();
+ }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java
index 1ecf5353fab..41d5bddfbca 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java
@@ -28,7 +28,7 @@ import org.sonar.batch.protocol.input.BatchInput;
import org.mockito.MockitoAnnotations;
import org.mockito.Mock;
import org.sonar.api.batch.rule.Rules;
-import org.sonar.batch.repository.user.UserRepository;
+import org.sonar.batch.repository.user.UserRepositoryLoader;
import org.sonar.batch.bootstrapper.IssueListener;
import org.junit.Before;
import com.google.common.collect.ImmutableList;
@@ -47,7 +47,7 @@ public class DefaultIssueCallbackTest {
@Mock
private IssueCache issueCache;
@Mock
- private UserRepository userRepository;
+ private UserRepositoryLoader userRepository;
@Mock
private Rules rules;
@@ -68,7 +68,7 @@ public class DefaultIssueCallbackTest {
BatchInput.User.Builder userBuilder = BatchInput.User.newBuilder();
userBuilder.setLogin("user");
userBuilder.setName("name");
- when(userRepository.loadFromWs(anyListOf(String.class))).thenReturn(ImmutableList.of(userBuilder.build()));
+ when(userRepository.load(anyListOf(String.class))).thenReturn(ImmutableList.of(userBuilder.build()));
Rule r = mock(Rule.class);
when(r.name()).thenReturn("rule name");
@@ -128,7 +128,7 @@ public class DefaultIssueCallbackTest {
}
};
- when(userRepository.loadFromWs(anyListOf(String.class))).thenReturn(new LinkedList<BatchInput.User>());
+ when(userRepository.load(anyListOf(String.class))).thenReturn(new LinkedList<BatchInput.User>());
when(rules.find(any(RuleKey.class))).thenReturn(null);
DefaultIssueCallback issueCallback = new DefaultIssueCallback(issueCache, listener, userRepository, rules);
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/DefaultServerLineHashesLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/DefaultServerLineHashesLoaderTest.java
index d1880ef7d3c..c7e2a40c04e 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/DefaultServerLineHashesLoaderTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/DefaultServerLineHashesLoaderTest.java
@@ -49,7 +49,7 @@ public class DefaultServerLineHashesLoaderTest {
@Test
public void should_download_source_from_ws_if_preview_mode() {
WSLoader wsLoader = mock(WSLoader.class);
- when(wsLoader.loadString(anyString())).thenReturn(new WSLoaderResult("ae12\n\n43fb", true));
+ when(wsLoader.loadString(anyString())).thenReturn(new WSLoaderResult<>("ae12\n\n43fb", true));
ServerLineHashesLoader lastSnapshots = new DefaultServerLineHashesLoader(wsLoader);
@@ -61,7 +61,7 @@ public class DefaultServerLineHashesLoaderTest {
@Test
public void should_download_source_with_space_from_ws_if_preview_mode() {
WSLoader server = mock(WSLoader.class);
- when(server.loadString(anyString())).thenReturn(new WSLoaderResult("ae12\n\n43fb", true));
+ when(server.loadString(anyString())).thenReturn(new WSLoaderResult<>("ae12\n\n43fb", true));
ServerLineHashesLoader lastSnapshots = new DefaultServerLineHashesLoader(server);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/BatchMediumTester.java
index 09c41cf4dcb..522d8b5fa1a 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/BatchMediumTester.java
@@ -19,8 +19,8 @@
*/
package org.sonar.batch.mediumtest;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonarqube.ws.Rules.ListResponse.Rule;
-
import org.sonar.batch.bootstrapper.IssueListener;
import org.sonar.api.server.rule.RulesDefinition.Repository;
import org.sonar.api.server.rule.RulesDefinition;
@@ -43,7 +43,6 @@ import java.util.Properties;
import org.sonar.api.CoreProperties;
import org.sonar.api.SonarPlugin;
-import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.batch.debt.internal.DefaultDebtModel;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
@@ -196,6 +195,7 @@ public class BatchMediumTester {
serverLineHashes.byKey.put(fileKey, lineHashes);
return this;
}
+
}
public void start() {
@@ -206,6 +206,10 @@ public class BatchMediumTester {
batch.stop();
}
+ public void syncProject(String projectKey) {
+ batch.syncProject(projectKey);
+ }
+
private BatchMediumTester(BatchMediumTesterBuilder builder) {
batch = Batch.builder()
.setEnableLoggingConfiguration(true)
@@ -341,7 +345,7 @@ public class BatchMediumTester {
private ProjectRepositories ref = new ProjectRepositories();
@Override
- public ProjectRepositories load(ProjectReactor reactor, AnalysisProperties taskProperties) {
+ public ProjectRepositories load(ProjectDefinition projDefinition, AnalysisProperties taskProperties) {
return ref;
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/cache/CacheSyncTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/cache/CacheSyncTest.java
new file mode 100644
index 00000000000..581c32789dc
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/cache/CacheSyncTest.java
@@ -0,0 +1,76 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.mediumtest.cache;
+
+import org.sonar.batch.protocol.input.FileData;
+
+import org.junit.Test;
+import org.junit.Rule;
+import com.google.common.collect.ImmutableMap;
+import org.junit.After;
+import org.sonar.api.CoreProperties;
+import org.sonar.batch.mediumtest.BatchMediumTester;
+import org.sonar.batch.protocol.input.ActiveRule;
+import org.sonar.xoo.XooPlugin;
+import org.sonar.xoo.rule.XooRulesDefinition;
+
+import java.util.Date;
+
+import org.junit.rules.TemporaryFolder;
+
+public class CacheSyncTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ public BatchMediumTester tester;
+
+ @After
+ public void stop() {
+ if (tester != null) {
+ tester.stop();
+ tester = null;
+ }
+ }
+
+ @Test
+ public void testSyncFirstTime() {
+ FileData file1 = new FileData("hash", true);
+ String[] hashes = new String[] {
+ "line1", "line2"
+ };
+
+ tester = BatchMediumTester.builder()
+ .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ISSUES))
+ .registerPlugin("xoo", new XooPlugin())
+ .addRules(new XooRulesDefinition())
+ .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "my/internal/key", "xoo"))
+ .setPreviousAnalysisDate(new Date())
+ .addFileData("test-project", "file1", file1)
+ .mockLineHashes("test-project:file1", hashes)
+ .build();
+
+ tester.start();
+ tester.syncProject("test-project");
+
+
+ }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/EmptyFileTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/EmptyFileTest.java
index f6849c64756..03e11861bd0 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/EmptyFileTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/EmptyFileTest.java
@@ -17,7 +17,7 @@
* 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.batch.mediumtest.preview;
+package org.sonar.batch.mediumtest.issuesmode;
import org.apache.commons.io.filefilter.FileFilterUtils;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/IssueModeAndReportsMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java
index 92743b4f125..9b0a4a7a643 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/IssueModeAndReportsMediumTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java
@@ -17,7 +17,7 @@
* 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.batch.mediumtest.preview;
+package org.sonar.batch.mediumtest.issuesmode;
import com.google.common.collect.ImmutableMap;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java
index 2d667f8d039..32f5fe36f59 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java
@@ -19,18 +19,20 @@
*/
package org.sonar.batch.repository;
+import org.apache.commons.io.IOUtils;
import org.sonar.batch.bootstrap.WSLoaderResult;
-
import com.google.common.collect.Maps;
+import java.io.IOException;
import java.util.Date;
+import static org.assertj.core.api.Assertions.assertThat;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.utils.MessageException;
import org.sonar.batch.bootstrap.AnalysisProperties;
import org.sonar.batch.bootstrap.GlobalMode;
@@ -52,7 +54,7 @@ public class DefaultProjectRepositoriesLoaderTest {
private DefaultProjectRepositoriesLoader loader;
private WSLoader wsLoader;
private GlobalMode globalMode;
- private ProjectReactor reactor;
+ private ProjectDefinition project;
private AnalysisProperties taskProperties;
@Before
@@ -68,30 +70,43 @@ public class DefaultProjectRepositoriesLoaderTest {
@Test
public void passPreviewParameter() {
addQualityProfile();
- reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo"));
- when(globalMode.isPreview()).thenReturn(false);
- loader.load(reactor, taskProperties);
+ project = ProjectDefinition.create().setKey("foo");
+ when(globalMode.isIssues()).thenReturn(false);
+ loader.load(project, taskProperties);
verify(wsLoader).loadString("/batch/project?key=foo&preview=false");
when(globalMode.isIssues()).thenReturn(true);
- loader.load(reactor, taskProperties);
+ loader.load(project, taskProperties);
verify(wsLoader).loadString("/batch/project?key=foo&preview=true");
}
@Test
+ public void deserializeResponse() throws IOException {
+ String resourceName = this.getClass().getSimpleName() + "/sample_response.json";
+ String response = IOUtils.toString(this.getClass().getResourceAsStream(resourceName));
+ when(wsLoader.loadString(anyString())).thenReturn(new WSLoaderResult<>(response, false));
+ project = ProjectDefinition.create().setKey("foo");
+ ProjectRepositories projectRepo = loader.load(project, taskProperties);
+
+ assertThat(projectRepo.activeRules().size()).isEqualTo(221);
+ assertThat(projectRepo.fileDataByPath("my:project").size()).isEqualTo(11);
+
+ }
+
+ @Test
public void passAndEncodeProjectKeyParameter() {
addQualityProfile();
- reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo bàr"));
- loader.load(reactor, taskProperties);
+ project = ProjectDefinition.create().setKey("foo bàr");
+ loader.load(project, taskProperties);
verify(wsLoader).loadString("/batch/project?key=foo+b%C3%A0r&preview=false");
}
@Test
public void passAndEncodeProfileParameter() {
addQualityProfile();
- reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo"));
+ project = ProjectDefinition.create().setKey("foo");
taskProperties.properties().put(ModuleQProfiles.SONAR_PROFILE_PROP, "my-profile#2");
- loader.load(reactor, taskProperties);
+ loader.load(project, taskProperties);
verify(wsLoader).loadString("/batch/project?key=foo&profile=my-profile%232&preview=false");
}
@@ -100,10 +115,10 @@ public class DefaultProjectRepositoriesLoaderTest {
thrown.expect(MessageException.class);
thrown.expectMessage("No quality profiles has been found this project, you probably don't have any language plugin suitable for this analysis.");
- reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo"));
+ project = ProjectDefinition.create().setKey("foo");
when(wsLoader.loadString(anyString())).thenReturn(new WSLoaderResult<>(new ProjectRepositories().toJson(), true));
- loader.load(reactor, taskProperties);
+ loader.load(project, taskProperties);
}
private void addQualityProfile() {
diff --git a/sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryLoaderTest.java
index 4aa5c91153d..bd0b3e7af88 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryLoaderTest.java
@@ -40,14 +40,14 @@ import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-public class UserRepositoryTest {
+public class UserRepositoryLoaderTest {
@Rule
public final ExpectedException exception = ExpectedException.none();
@Test
public void testLoad() throws IOException {
WSLoader wsLoader = mock(WSLoader.class);
- UserRepository userRepo = new UserRepository(wsLoader);
+ UserRepositoryLoader userRepo = new UserRepositoryLoader(wsLoader);
ByteArrayOutputStream out = new ByteArrayOutputStream();
BatchInput.User.Builder builder = BatchInput.User.newBuilder();
@@ -58,13 +58,13 @@ public class UserRepositoryTest {
when(wsLoader.loadSource("/batch/users?logins=fmallet,sbrandhof")).thenReturn(new WSLoaderResult<>(source, true));
when(source.openStream()).thenReturn(new ByteArrayInputStream(out.toByteArray()));
- assertThat(userRepo.loadFromWs(Arrays.asList("fmallet", "sbrandhof"))).extracting("login", "name").containsOnly(tuple("fmallet", "Freddy Mallet"), tuple("sbrandhof", "Simon"));
+ assertThat(userRepo.load(Arrays.asList("fmallet", "sbrandhof"))).extracting("login", "name").containsOnly(tuple("fmallet", "Freddy Mallet"), tuple("sbrandhof", "Simon"));
}
@Test
public void testInputStreamError() throws IOException {
WSLoader wsLoader = mock(WSLoader.class);
- UserRepository userRepo = new UserRepository(wsLoader);
+ UserRepositoryLoader userRepo = new UserRepositoryLoader(wsLoader);
ByteSource source = mock(ByteSource.class);
when(wsLoader.loadSource("/batch/users?logins=fmallet,sbrandhof")).thenReturn(new WSLoaderResult<>(source, true));
@@ -75,6 +75,6 @@ public class UserRepositoryTest {
exception.expect(IllegalStateException.class);
exception.expectMessage("Unable to get user details from server");
- assertThat(userRepo.loadFromWs(Arrays.asList("fmallet", "sbrandhof"))).extracting("login", "name").containsOnly(tuple("fmallet", "Freddy Mallet"), tuple("sbrandhof", "Simon"));
+ assertThat(userRepo.load(Arrays.asList("fmallet", "sbrandhof"))).extracting("login", "name").containsOnly(tuple("fmallet", "Freddy Mallet"), tuple("sbrandhof", "Simon"));
}
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/WSLoaderProjectProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectWSLoaderProviderTest.java
index c0366c40af6..d4fe0b2e109 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/WSLoaderProjectProviderTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectWSLoaderProviderTest.java
@@ -35,7 +35,7 @@ import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
-public class WSLoaderProjectProviderTest {
+public class ProjectWSLoaderProviderTest {
@Mock
private PersistentCache cache;
@@ -61,7 +61,6 @@ public class WSLoaderProjectProviderTest {
props = new AnalysisProperties(propMap, null);
WSLoader loader = loaderProvider.provide(props, mode, cache, client);
- assertThat(loader.getStrategy()).isEqualTo(LoadStrategy.SERVER_FIRST);
- assertThat(loader.isCacheEnabled()).isEqualTo(false);
+ assertThat(loader.getStrategy()).isEqualTo(LoadStrategy.SERVER_ONLY);
}
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java
index 74f2fa77106..a5392d36288 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java
@@ -46,7 +46,7 @@ import org.sonar.api.resources.Resource;
import org.sonar.api.rule.RuleKey;
import org.sonar.batch.issue.IssueCache;
import org.sonar.batch.protocol.input.BatchInput;
-import org.sonar.batch.repository.user.UserRepository;
+import org.sonar.batch.repository.user.UserRepositoryLoader;
import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.test.JsonAssert;
@@ -71,7 +71,7 @@ public class JSONReportTest {
Rules rules = mock(Rules.class);
Settings settings = new Settings();
IssueCache issueCache = mock(IssueCache.class);
- private UserRepository userRepository;
+ private UserRepositoryLoader userRepository;
@Before
public void before() throws Exception {
@@ -79,7 +79,7 @@ public class JSONReportTest {
SIMPLE_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+02:00"));
when(resource.getEffectiveKey()).thenReturn("Action.java");
when(server.getVersion()).thenReturn("3.6");
- userRepository = mock(UserRepository.class);
+ userRepository = mock(UserRepositoryLoader.class);
DefaultInputDir inputDir = new DefaultInputDir("struts", "src/main/java/org/apache/struts");
DefaultInputFile inputFile = new DefaultInputFile("struts", "src/main/java/org/apache/struts/Action.java");
inputFile.setStatus(InputFile.Status.CHANGED);
@@ -118,7 +118,7 @@ public class JSONReportTest {
when(issueCache.all()).thenReturn(Lists.newArrayList(issue));
BatchInput.User user1 = BatchInput.User.newBuilder().setLogin("julien").setName("Julien").build();
BatchInput.User user2 = BatchInput.User.newBuilder().setLogin("simon").setName("Simon").build();
- when(userRepository.loadFromWs(anyListOf(String.class))).thenReturn(Lists.newArrayList(user1, user2));
+ when(userRepository.load(anyListOf(String.class))).thenReturn(Lists.newArrayList(user1, user2));
StringWriter writer = new StringWriter();
jsonReport.writeJson(writer);
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest/sample_response.json b/sonar-batch/src/test/resources/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest/sample_response.json
new file mode 100644
index 00000000000..24522c42e15
--- /dev/null
+++ b/sonar-batch/src/test/resources/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest/sample_response.json
@@ -0,0 +1,2093 @@
+{
+ "timestamp": 0,
+ "qprofilesByLanguage": {
+ "java": {
+ "key": "java-sonar-way-95117",
+ "name": "Sonar way",
+ "language": "java",
+ "rulesUpdatedAt": "2015-08-06T17:02:00+0200"
+ }
+ },
+ "activeRules": [
+ {
+ "repositoryKey": "common-java",
+ "ruleKey": "DuplicatedBlocks",
+ "name": "Source files should not have any duplicated blocks",
+ "severity": "MAJOR",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "common-java",
+ "ruleKey": "InsufficientBranchCoverage",
+ "name": "Branches should have sufficient coverage by unit tests",
+ "severity": "MAJOR",
+ "language": "java",
+ "params": {
+ "minimumBranchCoverageRatio": "65.0"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S00105",
+ "name": "Tabulation characters should not be used",
+ "severity": "MINOR",
+ "internalKey": "S00105",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "MethodCyclomaticComplexity",
+ "name": "Methods should not be too complex",
+ "severity": "MAJOR",
+ "internalKey": "MethodCyclomaticComplexity",
+ "language": "java",
+ "params": {
+ "Threshold": "10"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "ClassCyclomaticComplexity",
+ "name": "Classes should not be too complex",
+ "severity": "MAJOR",
+ "internalKey": "ClassCyclomaticComplexity",
+ "language": "java",
+ "params": {
+ "max": "200"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "CommentedOutCodeLine",
+ "name": "Sections of code should not be \"commented out\"",
+ "severity": "MAJOR",
+ "internalKey": "CommentedOutCodeLine",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S00108",
+ "name": "Nested blocks of code should not be left empty",
+ "severity": "MAJOR",
+ "internalKey": "S00108",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S00107",
+ "name": "Methods should not have too many parameters",
+ "severity": "MAJOR",
+ "internalKey": "S00107",
+ "language": "java",
+ "params": {
+ "max": "7",
+ "constructorMax": "7"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S00112",
+ "name": "Generic exceptions should never be thrown",
+ "severity": "MAJOR",
+ "internalKey": "S00112",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S00100",
+ "name": "Method names should comply with a naming convention",
+ "severity": "MINOR",
+ "internalKey": "S00100",
+ "language": "java",
+ "params": {
+ "format": "^[a-z][a-zA-Z0-9]*$"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S00101",
+ "name": "Class names should comply with a naming convention",
+ "severity": "MINOR",
+ "internalKey": "S00101",
+ "language": "java",
+ "params": {
+ "format": "^[A-Z][a-zA-Z0-9]*$"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S00114",
+ "name": "Interface names should comply with a naming convention",
+ "severity": "MINOR",
+ "internalKey": "S00114",
+ "language": "java",
+ "params": {
+ "format": "^[A-Z][a-zA-Z0-9]*$"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S00115",
+ "name": "Constant names should comply with a naming convention",
+ "severity": "MINOR",
+ "internalKey": "S00115",
+ "language": "java",
+ "params": {
+ "format": "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S00116",
+ "name": "Field names should comply with a naming convention",
+ "severity": "MINOR",
+ "internalKey": "S00116",
+ "language": "java",
+ "params": {
+ "format": "^[a-z][a-zA-Z0-9]*$"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S3008",
+ "name": "Static non-final field names should comply with a naming convention",
+ "severity": "MINOR",
+ "internalKey": "S3008",
+ "language": "java",
+ "params": {
+ "format": "^[a-z][a-zA-Z0-9]*$"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S00117",
+ "name": "Local variable and method parameter names should comply with a naming convention",
+ "severity": "MINOR",
+ "internalKey": "S00117",
+ "language": "java",
+ "params": {
+ "format": "^[a-z][a-zA-Z0-9]*$"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S00119",
+ "name": "Type parameter names should comply with a naming convention",
+ "severity": "MINOR",
+ "internalKey": "S00119",
+ "language": "java",
+ "params": {
+ "format": "^[A-Z][0-9]?$"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S00120",
+ "name": "Package names should comply with a naming convention",
+ "severity": "MINOR",
+ "internalKey": "S00120",
+ "language": "java",
+ "params": {
+ "format": "^[a-z]+(\\.[a-z][a-z0-9]*)*$"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S00122",
+ "name": "Statements should be on separate lines",
+ "severity": "MINOR",
+ "internalKey": "S00122",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "RightCurlyBraceStartLineCheck",
+ "name": "A close curly brace should be located at the beginning of a line",
+ "severity": "MINOR",
+ "internalKey": "RightCurlyBraceStartLineCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "UselessParenthesesCheck",
+ "name": "Useless parentheses around expressions should be removed to prevent any misunderstanding",
+ "severity": "MAJOR",
+ "internalKey": "UselessParenthesesCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "ObjectFinalizeCheck",
+ "name": "The Object.finalize() method should not be called",
+ "severity": "CRITICAL",
+ "internalKey": "ObjectFinalizeCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "ObjectFinalizeOverridenCheck",
+ "name": "The Object.finalize() method should not be overriden",
+ "severity": "CRITICAL",
+ "internalKey": "ObjectFinalizeOverridenCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "ObjectFinalizeOverridenCallsSuperFinalizeCheck",
+ "name": "super.finalize() should be called at the end of Object.finalize() implementations",
+ "severity": "BLOCKER",
+ "internalKey": "ObjectFinalizeOverridenCallsSuperFinalizeCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "ClassVariableVisibilityCheck",
+ "name": "Class variable fields should not have public accessibility",
+ "severity": "MAJOR",
+ "internalKey": "ClassVariableVisibilityCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "ForLoopCounterChangedCheck",
+ "name": "\"for\" loop stop conditions should be invariant",
+ "severity": "MAJOR",
+ "internalKey": "ForLoopCounterChangedCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "LabelsShouldNotBeUsedCheck",
+ "name": "Labels should not be used",
+ "severity": "MAJOR",
+ "internalKey": "LabelsShouldNotBeUsedCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "SwitchLastCaseIsDefaultCheck",
+ "name": "\"switch\" statements should end with a \"default\" clause",
+ "severity": "MAJOR",
+ "internalKey": "SwitchLastCaseIsDefaultCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "EmptyStatementUsageCheck",
+ "name": "Empty statements should be removed",
+ "severity": "MINOR",
+ "internalKey": "EmptyStatementUsageCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "ModifiersOrderCheck",
+ "name": "Modifiers should be declared in the correct order",
+ "severity": "MINOR",
+ "internalKey": "ModifiersOrderCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "AssignmentInSubExpressionCheck",
+ "name": "Assignments should not be made from within sub-expressions",
+ "severity": "MAJOR",
+ "internalKey": "AssignmentInSubExpressionCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "UselessImportCheck",
+ "name": "Useless imports should be removed",
+ "severity": "MINOR",
+ "internalKey": "UselessImportCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "LowerCaseLongSuffixCheck",
+ "name": "Long suffix \"L\" should be upper case",
+ "severity": "MINOR",
+ "internalKey": "LowerCaseLongSuffixCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "MissingDeprecatedCheck",
+ "name": "Deprecated elements should have both the annotation and the Javadoc tag",
+ "severity": "MAJOR",
+ "internalKey": "MissingDeprecatedCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "HiddenFieldCheck",
+ "name": "Local variables should not shadow class fields",
+ "severity": "MAJOR",
+ "internalKey": "HiddenFieldCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1133",
+ "name": "Deprecated code should be removed eventually",
+ "severity": "INFO",
+ "internalKey": "S1133",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1134",
+ "name": "\"FIXME\" tags should be handled",
+ "severity": "MAJOR",
+ "internalKey": "S1134",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1135",
+ "name": "\"TODO\" tags should be handled",
+ "severity": "INFO",
+ "internalKey": "S1135",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1118",
+ "name": "Utility classes should not have public constructors",
+ "severity": "MAJOR",
+ "internalKey": "S1118",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1132",
+ "name": "Strings literals should be placed on the left side when checking for equality",
+ "severity": "MAJOR",
+ "internalKey": "S1132",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1126",
+ "name": "Return of boolean expressions should not be wrapped into an \"if-then-else\" statement",
+ "severity": "MINOR",
+ "internalKey": "S1126",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1125",
+ "name": "Literal boolean values should not be used in condition expressions",
+ "severity": "MINOR",
+ "internalKey": "S1125",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1067",
+ "name": "Expressions should not be too complex",
+ "severity": "MAJOR",
+ "internalKey": "S1067",
+ "language": "java",
+ "params": {
+ "max": "3"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1141",
+ "name": "Try-catch blocks should not be nested",
+ "severity": "MAJOR",
+ "internalKey": "S1141",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1147",
+ "name": "Exit methods should not be called",
+ "severity": "CRITICAL",
+ "internalKey": "S1147",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1143",
+ "name": "\"return\" statements should not occur in \"finally\" blocks",
+ "severity": "BLOCKER",
+ "internalKey": "S1143",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1157",
+ "name": "Case insensitive string comparisons should be made without intermediate upper or lower casing",
+ "severity": "MAJOR",
+ "internalKey": "S1157",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1155",
+ "name": "Collection.isEmpty() should be used to test for emptiness",
+ "severity": "MAJOR",
+ "internalKey": "S1155",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1149",
+ "name": "Synchronized classes Vector, Hashtable, Stack and StringBuffer should not be used",
+ "severity": "MAJOR",
+ "internalKey": "S1149",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1171",
+ "name": "Only static class initializers should be used",
+ "severity": "MAJOR",
+ "internalKey": "S1171",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1168",
+ "name": "Empty arrays and collections should be returned instead of null",
+ "severity": "MAJOR",
+ "internalKey": "S1168",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1170",
+ "name": "Public constants and fields initialized at declaration should be \"static final\" rather than merely \"final\"",
+ "severity": "MINOR",
+ "internalKey": "S1170",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1163",
+ "name": "Exceptions should not be thrown in finally blocks",
+ "severity": "MAJOR",
+ "internalKey": "S1163",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S106",
+ "name": "Standard ouputs should not be used directly to log anything",
+ "severity": "MAJOR",
+ "internalKey": "S106",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1165",
+ "name": "Exception classes should be immutable",
+ "severity": "MAJOR",
+ "internalKey": "S1165",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1066",
+ "name": "Collapsible \"if\" statements should be merged",
+ "severity": "MAJOR",
+ "internalKey": "S1066",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S134",
+ "name": "Control flow statements \"if\", \"for\", \"while\", \"switch\" and \"try\" should not be nested too deeply",
+ "severity": "MAJOR",
+ "internalKey": "S134",
+ "language": "java",
+ "params": {
+ "max": "3"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1181",
+ "name": "Throwable and Error should not be caught",
+ "severity": "BLOCKER",
+ "internalKey": "S1181",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1150",
+ "name": "Enumeration should not be implemented",
+ "severity": "MAJOR",
+ "internalKey": "S1150",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1182",
+ "name": "Classes that override \"clone\" should be \"Cloneable\" and call \"super.clone()\"",
+ "severity": "MAJOR",
+ "internalKey": "S1182",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1151",
+ "name": "\"switch case\" clauses should not have too many lines",
+ "severity": "MAJOR",
+ "internalKey": "S1151",
+ "language": "java",
+ "params": {
+ "max": "5"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S128",
+ "name": "Switch cases should end with an unconditional \"break\" statement",
+ "severity": "CRITICAL",
+ "internalKey": "S128",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1166",
+ "name": "Exception handlers should preserve the original exception",
+ "severity": "CRITICAL",
+ "internalKey": "S1166",
+ "language": "java",
+ "params": {
+ "exceptions": "java.lang.InterruptedException, java.lang.NumberFormatException, java.text.ParseException, java.net.MalformedURLException"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1190",
+ "name": "Future keywords should not be used as names",
+ "severity": "MAJOR",
+ "internalKey": "S1190",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1188",
+ "name": "Lambdas and anonymous classes should not have too many lines",
+ "severity": "MAJOR",
+ "internalKey": "S1188",
+ "language": "java",
+ "params": {
+ "Max": "20"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1191",
+ "name": "Classes from \"sun.*\" packages should not be used",
+ "severity": "MAJOR",
+ "internalKey": "S1191",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S135",
+ "name": "Loops should not contain more than a single \"break\" or \"continue\" statement",
+ "severity": "MAJOR",
+ "internalKey": "S135",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1186",
+ "name": "Methods should not be empty",
+ "severity": "MAJOR",
+ "internalKey": "S1186",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1185",
+ "name": "Overriding methods should do more than simply call the same method in the super class",
+ "severity": "MINOR",
+ "internalKey": "S1185",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1174",
+ "name": "\"Object.finalize()\" should remain protected (versus public) when overriding",
+ "severity": "MAJOR",
+ "internalKey": "S1174",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1175",
+ "name": "The signature of \"finalize()\" should match that of \"Object.finalize()\"",
+ "severity": "MAJOR",
+ "internalKey": "S1175",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1153",
+ "name": "String.valueOf() should not be appended to a String",
+ "severity": "MINOR",
+ "internalKey": "S1153",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1148",
+ "name": "Throwable.printStackTrace(...) should not be called",
+ "severity": "CRITICAL",
+ "internalKey": "S1148",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1195",
+ "name": "Array designators \"[]\" should be located after the type in method signatures",
+ "severity": "MINOR",
+ "internalKey": "S1195",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1194",
+ "name": "\"java.lang.Error\" should not be extended",
+ "severity": "MAJOR",
+ "internalKey": "S1194",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1193",
+ "name": "Exception types should not be tested using \"instanceof\" in catch blocks",
+ "severity": "MAJOR",
+ "internalKey": "S1193",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1192",
+ "name": "String literals should not be duplicated",
+ "severity": "MINOR",
+ "internalKey": "S1192",
+ "language": "java",
+ "params": {
+ "threshold": "3"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1158",
+ "name": "Primitive wrappers should not be instantiated only for \"toString\" or \"compareTo\" calls",
+ "severity": "MAJOR",
+ "internalKey": "S1158",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1215",
+ "name": "Execution of the Garbage Collector should be triggered only by the JVM",
+ "severity": "CRITICAL",
+ "internalKey": "S1215",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1197",
+ "name": "Array designators \"[]\" should be on the type, not the variable",
+ "severity": "MINOR",
+ "internalKey": "S1197",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1220",
+ "name": "The default unnamed package should not be used",
+ "severity": "MINOR",
+ "internalKey": "S1220",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1221",
+ "name": "Methods should not be named \"hashcode\" or \"equal\"",
+ "severity": "CRITICAL",
+ "internalKey": "S1221",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1199",
+ "name": "Nested code blocks should not be used",
+ "severity": "MAJOR",
+ "internalKey": "S1199",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1214",
+ "name": "Constants should not be defined in interfaces",
+ "severity": "MINOR",
+ "internalKey": "S1214",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1201",
+ "name": "Methods named \"equals\" should override Object.equals(Object)",
+ "severity": "CRITICAL",
+ "internalKey": "S1201",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1210",
+ "name": "\"equals(Object obj)\" should be overridden along with the \"compareTo(T obj)\" method",
+ "severity": "CRITICAL",
+ "internalKey": "S1210",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1206",
+ "name": "\"equals(Object obj)\" and \"hashCode()\" should be overridden in pairs",
+ "severity": "BLOCKER",
+ "internalKey": "S1206",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1219",
+ "name": "\"switch\" statements should not contain non-case labels",
+ "severity": "CRITICAL",
+ "internalKey": "S1219",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1301",
+ "name": "\"switch\" statements should have at least 3 \"case\" clauses",
+ "severity": "MINOR",
+ "internalKey": "S1301",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1314",
+ "name": "Octal values should not be used",
+ "severity": "MAJOR",
+ "internalKey": "S1314",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1226",
+ "name": "Method parameters, caught exceptions and foreach variables should not be reassigned",
+ "severity": "MAJOR",
+ "internalKey": "S1226",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1313",
+ "name": "IP addresses should not be hardcoded",
+ "severity": "MAJOR",
+ "internalKey": "S1313",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1312",
+ "name": "Loggers should be \"private static final\" and should share a naming convention",
+ "severity": "MINOR",
+ "internalKey": "S1312",
+ "language": "java",
+ "params": {
+ "format": "LOG(?:GER)?"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1223",
+ "name": "Non-constructor methods should not have the same name as the enclosing class",
+ "severity": "MAJOR",
+ "internalKey": "S1223",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1319",
+ "name": "Declarations should use Java collection interfaces such as \"List\" rather than specific implementation classes such as \"LinkedList\"",
+ "severity": "MAJOR",
+ "internalKey": "S1319",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1213",
+ "name": "The members of an interface declaration or class should appear in a pre-defined order",
+ "severity": "MINOR",
+ "internalKey": "S1213",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1444",
+ "name": ":",
+ "severity": "CRITICAL",
+ "internalKey": "S1444",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1452",
+ "name": "Generic wildcard types should not be used in return parameters",
+ "severity": "MAJOR",
+ "internalKey": "S1452",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1481",
+ "name": "Unused local variables should be removed",
+ "severity": "MAJOR",
+ "internalKey": "S1481",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1068",
+ "name": "Unused private fields should be removed",
+ "severity": "MAJOR",
+ "internalKey": "S1068",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1317",
+ "name": "\"StringBuilder\" and \"StringBuffer\" should not be instantiated with a character",
+ "severity": "MAJOR",
+ "internalKey": "S1317",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1596",
+ "name": "Collections.emptyList(), emptyMap() and emptySet() should be used instead of Collections.EMPTY_LIST, EMPTY_MAP and EMPTY_SET",
+ "severity": "MAJOR",
+ "internalKey": "S1596",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "UnusedPrivateMethod",
+ "name": "Unused private method should be removed",
+ "severity": "MAJOR",
+ "internalKey": "UnusedPrivateMethod",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "RedundantThrowsDeclarationCheck",
+ "name": "Throws declarations should not be superfluous",
+ "severity": "MINOR",
+ "internalKey": "RedundantThrowsDeclarationCheck",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1160",
+ "name": "Public methods should throw at most one checked exception",
+ "severity": "MAJOR",
+ "internalKey": "S1160",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1217",
+ "name": "Thread.run() and Runnable.run() should not be called directly",
+ "severity": "CRITICAL",
+ "internalKey": "S1217",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1862",
+ "name": "Related \"if/else if\" statements should not have the same condition",
+ "severity": "CRITICAL",
+ "internalKey": "S1862",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1488",
+ "name": "Local Variables should not be declared and then immediately returned or thrown",
+ "severity": "MINOR",
+ "internalKey": "S1488",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1602",
+ "name": "Lamdbas containing only one statement should not nest this statement in a block",
+ "severity": "MAJOR",
+ "internalKey": "S1602",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1611",
+ "name": "Parentheses should be removed from a single lambda input parameter when its type is inferred",
+ "severity": "MINOR",
+ "internalKey": "S1611",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1700",
+ "name": "A field should not duplicate the name of its containing class",
+ "severity": "MAJOR",
+ "internalKey": "S1700",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1172",
+ "name": "Unused method parameters should be removed",
+ "severity": "MAJOR",
+ "internalKey": "S1172",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1598",
+ "name": "Package declaration should match source file directory",
+ "severity": "MAJOR",
+ "internalKey": "S1598",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1873",
+ "name": "\"static final\" arrays should be \"private\"",
+ "severity": "CRITICAL",
+ "internalKey": "S1873",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1948",
+ "name": "Fields in a \"Serializable\" class should either be transient or serializable",
+ "severity": "CRITICAL",
+ "internalKey": "S1948",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1479",
+ "name": "\"switch\" statements should not have too many \"case\" clauses",
+ "severity": "MAJOR",
+ "internalKey": "S1479",
+ "language": "java",
+ "params": {
+ "maximum": "30"
+ }
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1764",
+ "name": "Identical expressions should not be used on both sides of a binary operator",
+ "severity": "CRITICAL",
+ "internalKey": "S1764",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1244",
+ "name": "Floating point numbers should not be tested for equality",
+ "severity": "CRITICAL",
+ "internalKey": "S1244",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2077",
+ "name": "Values passed to SQL commands should be sanitized",
+ "severity": "CRITICAL",
+ "internalKey": "S2077",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1161",
+ "name": "\"@Override\" annotation should be used on any method overriding (since Java 5) or implementing (since Java 6) another one",
+ "severity": "MAJOR",
+ "internalKey": "S1161",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1994",
+ "name": "\"for\" loop incrementers should modify the variable being tested in the loop\u0027s stop condition",
+ "severity": "CRITICAL",
+ "internalKey": "S1994",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2094",
+ "name": "Classes should not be empty",
+ "severity": "MAJOR",
+ "internalKey": "S2094",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1850",
+ "name": "\"instanceof\" operators that always return \"true\" or \"false\" should be removed",
+ "severity": "MAJOR",
+ "internalKey": "S1850",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1905",
+ "name": "Redundant casts should not be used",
+ "severity": "MINOR",
+ "internalKey": "S1905",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2114",
+ "name": "Collections should not be passed as arguments to their own methods",
+ "severity": "CRITICAL",
+ "internalKey": "S2114",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1065",
+ "name": "Unused labels should be removed",
+ "severity": "MAJOR",
+ "internalKey": "S1065",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2184",
+ "name": "Math operands should be cast before assignment",
+ "severity": "MAJOR",
+ "internalKey": "S2184",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2225",
+ "name": "\"toString()\" and \"clone()\" methods should not return null",
+ "severity": "CRITICAL",
+ "internalKey": "S2225",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2230",
+ "name": "Non-public methods should not be \"@Transactional\"",
+ "severity": "CRITICAL",
+ "internalKey": "S2230",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2200",
+ "name": "\"compareTo\" results should not be checked for specific values",
+ "severity": "MAJOR",
+ "internalKey": "S2200",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2092",
+ "name": "Cookies should be \"secure\"",
+ "severity": "CRITICAL",
+ "internalKey": "S2092",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1848",
+ "name": "Objects should not be created to be dropped immediately without being used",
+ "severity": "CRITICAL",
+ "internalKey": "S1848",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2235",
+ "name": "IllegalMonitorStateException should not be caught",
+ "severity": "CRITICAL",
+ "internalKey": "S2235",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S888",
+ "name": "Relational operators should be used in \"for\" loop termination conditions",
+ "severity": "CRITICAL",
+ "internalKey": "S888",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2068",
+ "name": "Credentials should not be hard-coded",
+ "severity": "CRITICAL",
+ "internalKey": "S2068",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2232",
+ "name": "\"ResultSet.isLast()\" should not be used",
+ "severity": "CRITICAL",
+ "internalKey": "S2232",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1849",
+ "name": "\"Iterator.hasNext()\" should not call \"Iterator.next()\"",
+ "severity": "BLOCKER",
+ "internalKey": "S1849",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2236",
+ "name": "Methods \"wait(...)\", \"notify()\" and \"notifyAll()\" should never be called on Thread instances",
+ "severity": "BLOCKER",
+ "internalKey": "S2236",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1844",
+ "name": "\"Object.wait(...)\" should never be called on objects that implement \"java.util.concurrent.locks.Condition\"",
+ "severity": "BLOCKER",
+ "internalKey": "S1844",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2251",
+ "name": "A \"for\" loop update clause should move the counter in the right direction",
+ "severity": "BLOCKER",
+ "internalKey": "S2251",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2252",
+ "name": "Loop conditions should be true at least once",
+ "severity": "CRITICAL",
+ "internalKey": "S2252",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2254",
+ "name": "\"HttpServletRequest.getRequestedSessionId()\" should not be used",
+ "severity": "CRITICAL",
+ "internalKey": "S2254",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2250",
+ "name": "\"ConcurrentLinkedQueue.size()\" should not be used",
+ "severity": "CRITICAL",
+ "internalKey": "S2250",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2226",
+ "name": "Servlets should never have mutable instance fields",
+ "severity": "CRITICAL",
+ "internalKey": "S2226",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2111",
+ "name": "\"BigDecimal(double)\" should not be used",
+ "severity": "CRITICAL",
+ "internalKey": "S2111",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2109",
+ "name": "Reflection should not be used to check non-runtime annotations",
+ "severity": "BLOCKER",
+ "internalKey": "S2109",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2273",
+ "name": "\"wait(...)\", \"notify()\" and \"notifyAll()\" methods should only be called when a lock is obviously held on an object",
+ "severity": "CRITICAL",
+ "internalKey": "S2273",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2276",
+ "name": "\"wait(...)\" should be used instead of \"Thread.sleep(...)\" when a lock is held",
+ "severity": "CRITICAL",
+ "internalKey": "S2276",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2274",
+ "name": "\"Object.wait(...)\" and \"Condition.await(...)\" should be called inside a \"while\" loop",
+ "severity": "CRITICAL",
+ "internalKey": "S2274",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2272",
+ "name": "\"Iterator.next()\" methods should throw \"NoSuchElementException\"",
+ "severity": "MAJOR",
+ "internalKey": "S2272",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2277",
+ "name": "Cryptographic RSA algorithms should always incorporate OAEP (Optimal Asymmetric Encryption Padding)",
+ "severity": "CRITICAL",
+ "internalKey": "S2277",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2204",
+ "name": "\".equals()\" should not be used to test the values of \"Atomic\" classes",
+ "severity": "BLOCKER",
+ "internalKey": "S2204",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2178",
+ "name": "Short-circuit logic should be used in boolean contexts",
+ "severity": "CRITICAL",
+ "internalKey": "S2178",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2116",
+ "name": "\"hashCode\" and \"toString\" should not be called on array instances",
+ "severity": "CRITICAL",
+ "internalKey": "S2116",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2157",
+ "name": "\"Cloneables\" should implement \"clone\"",
+ "severity": "CRITICAL",
+ "internalKey": "S2157",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2275",
+ "name": "Printf-style format strings should not lead to unexpected behavior at runtime",
+ "severity": "CRITICAL",
+ "internalKey": "S2275",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2151",
+ "name": "\"runFinalizersOnExit\" should not be called",
+ "severity": "BLOCKER",
+ "internalKey": "S2151",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2127",
+ "name": "\"Double.longBitsToDouble\" should not be used for \"int\"",
+ "severity": "BLOCKER",
+ "internalKey": "S2127",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1860",
+ "name": "Synchronization should not be based on Strings or boxed primitives",
+ "severity": "BLOCKER",
+ "internalKey": "S1860",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2055",
+ "name": "The non-serializable super class of a \"Serializable\" class must have a no-argument constructor",
+ "severity": "CRITICAL",
+ "internalKey": "S2055",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2118",
+ "name": "Non-serializable classes should not be written",
+ "severity": "CRITICAL",
+ "internalKey": "S2118",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2066",
+ "name": "\"Serializable\" inner classes of non-serializable classes should be \"static\"",
+ "severity": "CRITICAL",
+ "internalKey": "S2066",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2065",
+ "name": "Fields in non-serializable classes should not be \"transient\"",
+ "severity": "MINOR",
+ "internalKey": "S2065",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2061",
+ "name": "Custom serialization method signatures should meet requirements",
+ "severity": "CRITICAL",
+ "internalKey": "S2061",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2176",
+ "name": "Class names should not shadow interfaces or superclasses",
+ "severity": "MAJOR",
+ "internalKey": "S2176",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2130",
+ "name": "Parsing should be used to convert \"Strings\" to primitives",
+ "severity": "MAJOR",
+ "internalKey": "S2130",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2166",
+ "name": "Classes named like \"Exception\" should extend \"Exception\" or a subclass",
+ "severity": "MAJOR",
+ "internalKey": "S2166",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2153",
+ "name": "Boxing and unboxing should not be immediately reversed",
+ "severity": "MAJOR",
+ "internalKey": "S2153",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2326",
+ "name": "Unused type parameters should be removed",
+ "severity": "MAJOR",
+ "internalKey": "S2326",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2386",
+ "name": "Interfaces should not have \"public static\" mutable fields",
+ "severity": "CRITICAL",
+ "internalKey": "S2386",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2183",
+ "name": "Ints and longs should not be shifted by more than their number of bits-1",
+ "severity": "CRITICAL",
+ "internalKey": "S2183",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2167",
+ "name": "\"compareTo\" should not return \"Integer.MIN_VALUE\"",
+ "severity": "CRITICAL",
+ "internalKey": "S2167",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2165",
+ "name": "\"finalize\" should not set fields to \"null\"",
+ "severity": "MAJOR",
+ "internalKey": "S2165",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2122",
+ "name": "\"ScheduledThreadPoolExecutor\" should not have 0 core threads",
+ "severity": "BLOCKER",
+ "internalKey": "S2122",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2134",
+ "name": "Classes extending java.lang.Thread should override the \"run\" method",
+ "severity": "MAJOR",
+ "internalKey": "S2134",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2175",
+ "name": "Inappropriate \"Collection\" calls should not be made",
+ "severity": "CRITICAL",
+ "internalKey": "S2175",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2447",
+ "name": "Null should not be returned from a \"Boolean\" method",
+ "severity": "CRITICAL",
+ "internalKey": "S2447",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2131",
+ "name": "Primitives should not be boxed just for \"String\" conversion",
+ "severity": "MAJOR",
+ "internalKey": "S2131",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2437",
+ "name": "Silly bit operations should not be performed",
+ "severity": "MAJOR",
+ "internalKey": "S2437",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2110",
+ "name": "Invalid \"Date\" values should not be used",
+ "severity": "CRITICAL",
+ "internalKey": "S2110",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2160",
+ "name": "Subclasses that add fields should override \"equals\"",
+ "severity": "MAJOR",
+ "internalKey": "S2160",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1872",
+ "name": "Classes should not be compared by name",
+ "severity": "CRITICAL",
+ "internalKey": "S1872",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2440",
+ "name": "Classes with only \"static\" methods should not be instantiated",
+ "severity": "MAJOR",
+ "internalKey": "S2440",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2441",
+ "name": "Non-serializable objects should not be stored in \"HttpSessions\"",
+ "severity": "CRITICAL",
+ "internalKey": "S2441",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2123",
+ "name": "Values should not be uselessly incremented",
+ "severity": "CRITICAL",
+ "internalKey": "S2123",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2133",
+ "name": "Objects should not be created only to \"getClass\"",
+ "severity": "MAJOR",
+ "internalKey": "S2133",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2154",
+ "name": "Dissimilar primitive wrappers should not be used with the ternary operator without explicit casting",
+ "severity": "CRITICAL",
+ "internalKey": "S2154",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2442",
+ "name": "\"Lock\" objects should not be \"synchronized\"",
+ "severity": "BLOCKER",
+ "internalKey": "S2442",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2388",
+ "name": "Inner class calls to super class methods should be unambiguous",
+ "severity": "MAJOR",
+ "internalKey": "S2388",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2438",
+ "name": "\"Threads\" should not be used where \"Runnables\" are expected",
+ "severity": "CRITICAL",
+ "internalKey": "S2438",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2259",
+ "name": "Null pointers should not be dereferenced",
+ "severity": "BLOCKER",
+ "internalKey": "S2259",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2583",
+ "name": "Conditions should not unconditionally evaluate to \"TRUE\" or to \"FALSE\"",
+ "severity": "BLOCKER",
+ "internalKey": "S2583",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2696",
+ "name": "Instance methods should not write to \"static\" fields",
+ "severity": "CRITICAL",
+ "internalKey": "S2696",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2674",
+ "name": "The value returned from a stream read should be checked",
+ "severity": "CRITICAL",
+ "internalKey": "S2674",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2695",
+ "name": "\"PreparedStatement\" and \"ResultSet\" methods should be called with valid indices",
+ "severity": "BLOCKER",
+ "internalKey": "S2695",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2112",
+ "name": "\"URL.hashCode\" and \"URL.equals\" should be avoided",
+ "severity": "CRITICAL",
+ "internalKey": "S2112",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2387",
+ "name": "Child class members should not shadow parent class members",
+ "severity": "MAJOR",
+ "internalKey": "S2387",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2786",
+ "name": "Nested \"enum\"s should not be declared static",
+ "severity": "MAJOR",
+ "internalKey": "S2786",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2095",
+ "name": "Resources should be closed",
+ "severity": "BLOCKER",
+ "internalKey": "S2095",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2677",
+ "name": "\"read\" and \"readLine\" return values should be used",
+ "severity": "BLOCKER",
+ "internalKey": "S2677",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1858",
+ "name": "\"toString()\" should never be called on a String object",
+ "severity": "MAJOR",
+ "internalKey": "S1858",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2864",
+ "name": "\"entrySet()\" should be iterated when both the key and value are needed",
+ "severity": "MAJOR",
+ "internalKey": "S2864",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2692",
+ "name": "\"indexOf\" checks should not be for positive numbers",
+ "severity": "CRITICAL",
+ "internalKey": "S2692",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2675",
+ "name": "\"readObject\" should not be \"synchronized\"",
+ "severity": "MAJOR",
+ "internalKey": "S2675",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2676",
+ "name": "Neither \"Math.abs\" nor negation should be used on numbers that could be \"MIN_VALUE\"",
+ "severity": "CRITICAL",
+ "internalKey": "S2676",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2885",
+ "name": "\"Calendars\" and \"DateFormats\" should not be static",
+ "severity": "CRITICAL",
+ "internalKey": "S2885",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2222",
+ "name": "Locks should be released",
+ "severity": "CRITICAL",
+ "internalKey": "S2222",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2097",
+ "name": "\"equals(Object obj)\" should test argument type",
+ "severity": "BLOCKER",
+ "internalKey": "S2097",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2185",
+ "name": "Silly math should not be performed",
+ "severity": "MAJOR",
+ "internalKey": "S2185",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2159",
+ "name": "Silly equality checks should not be made",
+ "severity": "MAJOR",
+ "internalKey": "S2159",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2912",
+ "name": "\"indexOf\" checks should use a start position",
+ "severity": "MAJOR",
+ "internalKey": "S2912",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2325",
+ "name": "\"private\" methods that don\u0027t access instance data should be \"static\"",
+ "severity": "MINOR",
+ "internalKey": "S2325",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1264",
+ "name": "A \"while\" loop should be used instead of a \"for\" loop",
+ "severity": "MINOR",
+ "internalKey": "S1264",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2681",
+ "name": "Multiline blocks should be enclosed in curly braces",
+ "severity": "CRITICAL",
+ "internalKey": "S2681",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S1640",
+ "name": "Maps with keys that are enum values should be replaced with EnumMap",
+ "severity": "MAJOR",
+ "internalKey": "S1640",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2976",
+ "name": "\"File.createTempFile\" should not be used to create a directory",
+ "severity": "CRITICAL",
+ "internalKey": "S2976",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2188",
+ "name": "JUnit test cases should call super methods",
+ "severity": "CRITICAL",
+ "internalKey": "S2188",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2186",
+ "name": "JUnit assertions should not be used in \"run\" methods",
+ "severity": "CRITICAL",
+ "internalKey": "S2186",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2187",
+ "name": "TestCases should contain tests",
+ "severity": "MAJOR",
+ "internalKey": "S2187",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2391",
+ "name": "JUnit framework methods should be declared properly",
+ "severity": "CRITICAL",
+ "internalKey": "S2391",
+ "language": "java",
+ "params": {}
+ },
+ {
+ "repositoryKey": "squid",
+ "ruleKey": "S2970",
+ "name": "Assertions should be complete",
+ "severity": "CRITICAL",
+ "internalKey": "S2970",
+ "language": "java",
+ "params": {}
+ }
+ ],
+ "settingsByModule": {},
+ "fileDataByModuleAndPath": {
+ "my:project": {
+ "src/test/java/org/sonar/plugins/scm/jazzrtc/UTCRule.java": {
+ "hash": "e80b5df219bc78ed5c498988d9f23d37",
+ "needBlame": true
+ },
+ "src/test/java/org/sonar/plugins/scm/jazzrtc/JazzRtcScmProviderTest.java": {
+ "hash": "6f4f93e1016714869a2008de7df3d207",
+ "needBlame": true
+ },
+ "src/test/java/org/sonar/plugins/scm/jazzrtc/JazzRtcBlameCommandTest.java": {
+ "hash": "0ab25adb0ae40d826ea23998a362a7ef",
+ "needBlame": true
+ },
+ "src/main/java/org/sonar/plugins/scm/jazzrtc/JazzRtcConfiguration.java": {
+ "hash": "23961c33f6388248ae3530dbc8988e72",
+ "needBlame": true
+ },
+ "src/main/java/org/sonar/plugins/scm/jazzrtc/package-info.java": {
+ "hash": "afdb44120bc13f6fd36be27040408ac0",
+ "needBlame": true
+ },
+ "src/test/java/org/sonar/plugins/scm/jazzrtc/JazzRtcBlameConsumerTest.java": {
+ "hash": "cd9f105580a53c702e0b721899314348",
+ "needBlame": true
+ },
+ "src/main/java/org/sonar/plugins/scm/jazzrtc/JazzRtcBlameConsumer.java": {
+ "hash": "fff6441cd4193c275f12221355658883",
+ "needBlame": true
+ },
+ "src/main/java/org/sonar/plugins/scm/jazzrtc/JazzRtcScmProvider.java": {
+ "hash": "f047b734b6653a5126f8c278dc6aa1a5",
+ "needBlame": true
+ },
+ "src/test/java/org/sonar/plugins/scm/jazzrtc/JazzRtcPluginTest.java": {
+ "hash": "688b065dcf12a55b363acf7901f9a6de",
+ "needBlame": true
+ },
+ "src/main/java/org/sonar/plugins/scm/jazzrtc/JazzRtcBlameCommand.java": {
+ "hash": "9646e0be0c460017af98505e8ab5578a",
+ "needBlame": true
+ },
+ "src/main/java/org/sonar/plugins/scm/jazzrtc/JazzRtcPlugin.java": {
+ "hash": "c9fd9a67b28d610165edbb29d8975d00",
+ "needBlame": true
+ }
+ }
+ },
+ "lastAnalysisDate": "2015-08-06T17:06:58+0200"
+} \ No newline at end of file