]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6864 Rename WS batch/* to scanner/*
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Mon, 21 Sep 2015 12:34:41 +0000 (14:34 +0200)
committerDuarte Meneses <duarte.meneses@sonarsource.com>
Wed, 30 Sep 2015 14:27:12 +0000 (16:27 +0200)
64 files changed:
it/it-tests/src/test/java/server/suite/ServerTest.java
server/sonar-server/src/main/java/org/sonar/server/batch/BatchIndex.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/batch/BatchWs.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/batch/BatchWsAction.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/batch/BatchWsModule.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/batch/GlobalAction.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/batch/IssuesAction.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/batch/Messages.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/batch/ProjectAction.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataQuery.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/batch/UsersAction.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/batch/package-info.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/main/java/org/sonar/server/scanner/GlobalAction.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/scanner/IssuesAction.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/scanner/Messages.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/scanner/ProjectAction.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/scanner/ProjectDataLoader.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/scanner/ProjectDataQuery.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/scanner/ScannerIndex.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/scanner/ScannerWs.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/scanner/ScannerWsAction.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/scanner/ScannerWsModule.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/scanner/UsersAction.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/scanner/package-info.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/batch/BatchIndexTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsModuleTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/batch/GlobalActionTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderMediumTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/batch/UsersActionTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/scanner/GlobalActionTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/scanner/IssuesActionTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/scanner/ProjectActionTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/scanner/ProjectDataLoaderMediumTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/scanner/ScannerIndexTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/scanner/ScannerWsModuleTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/scanner/ScannerWsTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/scanner/UsersActionTest.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_global_referentials.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_global_settings.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_only_license_settings_without_scan_but_with_preview_permission.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectActionTest/project_referentials.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/scanner/GlobalActionTest/return_global_referentials.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/scanner/GlobalActionTest/return_global_settings.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/scanner/GlobalActionTest/return_only_license_settings_without_scan_but_with_preview_permission.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/scanner/ProjectActionTest/project_referentials.json [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/config/routes.rb
sonar-batch/src/main/java/org/sonar/batch/repository/DefaultGlobalRepositoriesLoader.java
sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java
sonar-batch/src/main/java/org/sonar/batch/repository/DefaultServerIssuesLoader.java
sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepositoryLoader.java
sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheSynchronizerTest.java
sonar-batch/src/test/java/org/sonar/batch/repository/DefaultGlobalRepositoriesLoaderTest.java
sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java
sonar-batch/src/test/java/org/sonar/batch/repository/DefaultServerIssuesLoaderTest.java
sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryLoaderTest.java
sonar-ws/src/main/gen-java/org/sonarqube/ws/WsBatch.java [deleted file]
sonar-ws/src/main/gen-java/org/sonarqube/ws/WsScanner.java [new file with mode: 0644]
sonar-ws/src/main/protobuf/ws-batch.proto [deleted file]
sonar-ws/src/main/protobuf/ws-scanner.proto [new file with mode: 0644]

index 57ab6c3b33f14664c7c97026bcf962a44048b1d4..7e6a4ae70492a96f01be2ab6020b88605da23f63 100644 (file)
@@ -72,7 +72,7 @@ public class ServerTest {
       orchestrator.getServer().getAdminWsClient().update(new PropertyUpdateQuery("sonar.forceAuthentication", "true"));
 
       // /batch/index should never need authentication
-      String batchIndex = orchestrator.getServer().wsClient().get("/batch/index");
+      String batchIndex = orchestrator.getServer().wsClient().get("/scanner/index");
       assertThat(batchIndex).isNotEmpty();
 
       String jar = batchIndex.split("\\|")[0];
@@ -80,13 +80,13 @@ public class ServerTest {
       // /batch/file should never need authentication
       HttpClient httpclient = new DefaultHttpClient();
       try {
-        HttpGet get = new HttpGet(orchestrator.getServer().getUrl() + "/batch/file?name=" + jar);
+        HttpGet get = new HttpGet(orchestrator.getServer().getUrl() + "/scanner/file?name=" + jar);
         HttpResponse response = httpclient.execute(get);
         assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);
         EntityUtils.consume(response.getEntity());
 
         // As Sonar runner is still using /batch/key, we have to also verify it
-        get = new HttpGet(orchestrator.getServer().getUrl() + "/batch/" + jar);
+        get = new HttpGet(orchestrator.getServer().getUrl() + "/scanner/" + jar);
         response = httpclient.execute(get);
         assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);
         EntityUtils.consume(response.getEntity());
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/BatchIndex.java b/server/sonar-server/src/main/java/org/sonar/server/batch/BatchIndex.java
deleted file mode 100644 (file)
index 77ab803..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.server.batch;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.filefilter.FileFilterUtils;
-import org.apache.commons.io.filefilter.HiddenFileFilter;
-import org.apache.commons.lang.CharUtils;
-import org.apache.commons.lang.StringUtils;
-import org.picocontainer.Startable;
-import org.sonar.api.server.ServerSide;
-import org.sonar.api.platform.Server;
-import org.sonar.home.cache.FileHashes;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-
-/**
- * JAR files to be downloaded by sonar-runner.
- */
-@ServerSide
-public class BatchIndex implements Startable {
-
-  private final Server server;
-  private String index;
-  private File batchDir;
-
-  public BatchIndex(Server server) {
-    this.server = server;
-  }
-
-  @Override
-  public void start() {
-    StringBuilder sb = new StringBuilder();
-    batchDir = new File(server.getRootDir(), "lib/batch");
-    if (batchDir.exists()) {
-      Collection<File> files = FileUtils.listFiles(batchDir, HiddenFileFilter.VISIBLE, FileFilterUtils.directoryFileFilter());
-      for (File file : files) {
-        String filename = file.getName();
-        if (StringUtils.endsWith(filename, ".jar")) {
-          sb.append(filename).append('|').append(new FileHashes().of(file)).append(CharUtils.LF);
-        }
-      }
-    }
-    this.index = sb.toString();
-  }
-
-  @Override
-  public void stop() {
-    // Nothing to do
-  }
-
-  String getIndex() {
-    return index;
-  }
-
-  File getFile(String filename) {
-    try {
-      File input = new File(batchDir, filename);
-      if (!input.exists() || !FileUtils.directoryContains(batchDir, input)) {
-        throw new IllegalArgumentException("Bad filename: " + filename);
-      }
-      return input;
-
-    } catch (IOException e) {
-      throw new IllegalStateException("Can get file " + filename, e);
-    }
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWs.java b/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWs.java
deleted file mode 100644 (file)
index df6a4bc..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.server.batch;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.RequestHandler;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-
-import java.io.IOException;
-
-public class BatchWs implements WebService {
-
-  public static final String API_ENDPOINT = "batch";
-
-  private final BatchIndex batchIndex;
-  private final BatchWsAction[] actions;
-
-  public BatchWs(BatchIndex batchIndex, BatchWsAction... actions) {
-    this.batchIndex = batchIndex;
-    this.actions = actions;
-  }
-
-  @Override
-  public void define(Context context) {
-    NewController controller = context.createController(API_ENDPOINT)
-      .setSince("4.4")
-      .setDescription("Get JAR files and referentials for batch");
-
-    defineIndexAction(controller);
-    defineFileAction(controller);
-    for (BatchWsAction action : actions) {
-      action.define(controller);
-    }
-
-    controller.done();
-  }
-
-  private void defineIndexAction(NewController controller) {
-    controller.createAction("index")
-      .setInternal(true)
-      .setDescription("List the JAR files to be downloaded by source analyzer")
-      .setHandler(new RequestHandler() {
-        @Override
-        public void handle(Request request, Response response) {
-          try {
-            response.stream().setMediaType("text/plain");
-            IOUtils.write(batchIndex.getIndex(), response.stream().output());
-          } catch (IOException e) {
-            throw new IllegalStateException(e);
-          }
-        }
-      })
-      .setResponseExample(getClass().getResource("example-batch-index.txt"));
-  }
-
-  private void defineFileAction(NewController controller) {
-    controller.createAction("file")
-      .setInternal(true)
-      .setDescription("Download a JAR file required by source analyzer")
-      .setHandler(new RequestHandler() {
-        @Override
-        public void handle(Request request, Response response) {
-          String filename = request.mandatoryParam("name");
-          try {
-            response.stream().setMediaType("application/java-archive");
-            FileUtils.copyFile(batchIndex.getFile(filename), response.stream().output());
-          } catch (IOException e) {
-            throw new IllegalStateException(e);
-          }
-        }
-      })
-      .createParam("name")
-      .setDescription("File name")
-      .setExampleValue("batch-library-2.3.jar");
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWsAction.java
deleted file mode 100644 (file)
index 66f279a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.server.batch;
-
-import org.sonar.server.ws.WsAction;
-
-public interface BatchWsAction extends WsAction {
-  // Marker interface
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/batch/BatchWsModule.java
deleted file mode 100644 (file)
index 3ea7bba..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.server.batch;
-
-import org.sonar.core.platform.Module;
-
-public class BatchWsModule extends Module {
-  @Override
-  protected void configureModule() {
-    add(
-      BatchIndex.class,
-      GlobalAction.class,
-      ProjectAction.class,
-      ProjectDataLoader.class,
-      IssuesAction.class,
-      UsersAction.class,
-      BatchWs.class);
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/GlobalAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/GlobalAction.java
deleted file mode 100644 (file)
index f528f93..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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.server.batch;
-
-import org.apache.commons.io.IOUtils;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.batch.protocol.input.GlobalRepositories;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.MyBatis;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.db.property.PropertiesDao;
-import org.sonar.db.property.PropertyDto;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.plugins.MimeTypes;
-import org.sonar.server.user.UserSession;
-
-public class GlobalAction implements BatchWsAction {
-
-  private final DbClient dbClient;
-  private final PropertiesDao propertiesDao;
-  private final UserSession userSession;
-
-  public GlobalAction(DbClient dbClient, PropertiesDao propertiesDao, UserSession userSession) {
-    this.dbClient = dbClient;
-    this.propertiesDao = propertiesDao;
-    this.userSession = userSession;
-  }
-
-  @Override
-  public void define(WebService.NewController controller) {
-    controller.createAction("global")
-      .setDescription("Return metrics and global properties")
-      .setSince("4.5")
-      .setInternal(true)
-      .setHandler(this);
-  }
-
-  @Override
-  public void handle(Request request, Response response) throws Exception {
-    boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
-    boolean hasPreviewPerm = userSession.hasGlobalPermission(GlobalPermissions.PREVIEW_EXECUTION);
-    if (!hasPreviewPerm && !hasScanPerm) {
-      throw new ForbiddenException(Messages.NO_PERMISSION);
-    }
-
-    DbSession session = dbClient.openSession(false);
-    try {
-      GlobalRepositories ref = new GlobalRepositories();
-      addMetrics(ref, session);
-      addSettings(ref, hasScanPerm, hasPreviewPerm, session);
-
-      response.stream().setMediaType(MimeTypes.JSON);
-      IOUtils.write(ref.toJson(), response.stream().output());
-    } finally {
-      MyBatis.closeQuietly(session);
-    }
-  }
-
-  private void addMetrics(GlobalRepositories ref, DbSession session) {
-    for (MetricDto metric : dbClient.metricDao().selectEnabled(session)) {
-      ref.addMetric(
-        new org.sonar.batch.protocol.input.Metric(metric.getId(), metric.getKey(),
-          metric.getValueType(),
-          metric.getDescription(),
-          metric.getDirection(),
-          metric.getKey(),
-          metric.isQualitative(),
-          metric.isUserManaged(),
-          metric.getWorstValue(),
-          metric.getBestValue(),
-          metric.isOptimizedBestValue()));
-    }
-  }
-
-  private void addSettings(GlobalRepositories ref, boolean hasScanPerm, boolean hasPreviewPerm, DbSession session) {
-    for (PropertyDto propertyDto : propertiesDao.selectGlobalProperties(session)) {
-      String key = propertyDto.getKey();
-      String value = propertyDto.getValue();
-
-      if (isPropertyAllowed(key, hasScanPerm, hasPreviewPerm)) {
-        ref.addGlobalSetting(key, value);
-      }
-    }
-  }
-
-  private static boolean isPropertyAllowed(String key, boolean hasScanPerm, boolean hasPreviewPerm) {
-    return !key.contains(".secured") || hasScanPerm || (key.contains(".license") && hasPreviewPerm);
-  }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/IssuesAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/IssuesAction.java
deleted file mode 100644 (file)
index 6e3042a..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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.server.batch;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import org.sonar.api.resources.Scopes;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.batch.protocol.input.BatchInput;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.MyBatis;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.issue.index.IssueDoc;
-import org.sonar.server.issue.index.IssueIndex;
-import org.sonar.server.plugins.MimeTypes;
-import org.sonar.server.user.UserSession;
-
-import static com.google.common.collect.Maps.newHashMap;
-
-public class IssuesAction implements BatchWsAction {
-
-  private static final String PARAM_KEY = "key";
-
-  private final DbClient dbClient;
-  private final IssueIndex issueIndex;
-  private final UserSession userSession;
-  private final ComponentFinder componentFinder;
-
-  public IssuesAction(DbClient dbClient, IssueIndex issueIndex, UserSession userSession, ComponentFinder componentFinder) {
-    this.dbClient = dbClient;
-    this.issueIndex = issueIndex;
-    this.userSession = userSession;
-    this.componentFinder = componentFinder;
-  }
-
-  @Override
-  public void define(WebService.NewController controller) {
-    WebService.NewAction action = controller.createAction("issues")
-      .setDescription("Return open issues")
-      .setSince("5.1")
-      .setInternal(true)
-      .setHandler(this);
-
-    action
-      .createParam(PARAM_KEY)
-      .setRequired(true)
-      .setDescription("Project, module or file key")
-      .setExampleValue("org.codehaus.sonar:sonar");
-  }
-
-  @Override
-  public void handle(Request request, Response response) throws Exception {
-    userSession.checkGlobalPermission(GlobalPermissions.PREVIEW_EXECUTION);
-    final String moduleKey = request.mandatoryParam(PARAM_KEY);
-
-    response.stream().setMediaType(MimeTypes.PROTOBUF);
-    DbSession session = dbClient.openSession(false);
-    try {
-      ComponentDto component = componentFinder.getByKey(session, moduleKey);
-      Map<String, String> keysByUUid = keysByUUid(session, component);
-
-      BatchInput.ServerIssue.Builder issueBuilder = BatchInput.ServerIssue.newBuilder();
-      for (Iterator<IssueDoc> issueDocIterator = issueIndex.selectIssuesForBatch(component); issueDocIterator.hasNext();) {
-        handleIssue(issueDocIterator.next(), issueBuilder, keysByUUid, response.stream().output());
-      }
-    } finally {
-      MyBatis.closeQuietly(session);
-    }
-  }
-
-  private static void handleIssue(IssueDoc issue, BatchInput.ServerIssue.Builder issueBuilder, Map<String, String> keysByUUid, OutputStream out) {
-    issueBuilder.setKey(issue.key());
-    issueBuilder.setModuleKey(keysByUUid.get(issue.moduleUuid()));
-    String path = issue.filePath();
-    if (path != null) {
-      issueBuilder.setPath(path);
-    }
-    issueBuilder.setRuleRepository(issue.ruleKey().repository());
-    issueBuilder.setRuleKey(issue.ruleKey().rule());
-    String checksum = issue.checksum();
-    if (checksum != null) {
-      issueBuilder.setChecksum(checksum);
-    }
-    String assigneeLogin = issue.assignee();
-    if (assigneeLogin != null) {
-      issueBuilder.setAssigneeLogin(assigneeLogin);
-    }
-    Integer line = issue.line();
-    if (line != null) {
-      issueBuilder.setLine(line);
-    }
-    String message = issue.message();
-    if (message != null) {
-      issueBuilder.setMsg(message);
-    }
-    issueBuilder.setSeverity(org.sonar.batch.protocol.Constants.Severity.valueOf(issue.severity()));
-    issueBuilder.setManualSeverity(issue.isManualSeverity());
-    issueBuilder.setStatus(issue.status());
-    String resolution = issue.resolution();
-    if (resolution != null) {
-      issueBuilder.setResolution(resolution);
-    }
-    issueBuilder.setCreationDate(issue.creationDate().getTime());
-    try {
-      issueBuilder.build().writeDelimitedTo(out);
-    } catch (IOException e) {
-      throw new IllegalStateException("Unable to serialize issue", e);
-    }
-    issueBuilder.clear();
-  }
-
-  private Map<String, String> keysByUUid(DbSession session, ComponentDto component) {
-    Map<String, String> keysByUUid = newHashMap();
-    if (Scopes.PROJECT.equals(component.scope())) {
-      List<ComponentDto> modulesTree = dbClient.componentDao().selectDescendantModules(session, component.uuid());
-      for (ComponentDto componentDto : modulesTree) {
-        keysByUUid.put(componentDto.uuid(), componentDto.key());
-      }
-    } else {
-      String moduleUuid = component.moduleUuid();
-      if (moduleUuid == null) {
-        throw new IllegalArgumentException(String.format("The component '%s' has no module uuid", component.uuid()));
-      }
-      ComponentDto module = dbClient.componentDao().selectOrFailByUuid(session, moduleUuid);
-      keysByUUid.put(module.uuid(), module.key());
-    }
-    return keysByUUid;
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/Messages.java b/server/sonar-server/src/main/java/org/sonar/server/batch/Messages.java
deleted file mode 100644 (file)
index a08a8ce..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.server.batch;
-
-public interface Messages {
-
-  String NO_PERMISSION = "You're not authorized to execute any SonarQube analysis. Please contact your SonarQube administrator.";
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectAction.java
deleted file mode 100644 (file)
index df43571..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * 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.server.batch;
-
-import java.util.HashMap;
-import java.util.Map;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.batch.protocol.input.FileData;
-import org.sonar.batch.protocol.input.ProjectRepositories;
-import org.sonarqube.ws.WsBatch.WsProjectResponse;
-
-import static org.sonar.server.ws.WsUtils.writeProtobuf;
-
-public class ProjectAction implements BatchWsAction {
-
-  private static final String PARAM_KEY = "key";
-  private static final String PARAM_PROFILE = "profile";
-  private static final String PARAM_PREVIEW = "preview";
-
-  private final ProjectDataLoader projectDataLoader;
-
-  public ProjectAction(ProjectDataLoader projectDataLoader) {
-    this.projectDataLoader = projectDataLoader;
-  }
-
-  @Override
-  public void define(WebService.NewController controller) {
-    WebService.NewAction action = controller.createAction("project")
-      .setDescription("Return project repository")
-      .setSince("4.5")
-      .setInternal(true)
-      .setHandler(this);
-
-    action
-      .createParam(PARAM_KEY)
-      .setRequired(true)
-      .setDescription("Project or module key")
-      .setExampleValue("org.codehaus.sonar:sonar");
-
-    action
-      .createParam(PARAM_PROFILE)
-      .setDescription("Profile name")
-      .setExampleValue("SonarQube Way");
-
-    action
-      .createParam(PARAM_PREVIEW)
-      .setDescription("Preview mode or not")
-      .setDefaultValue(false)
-      .setBooleanPossibleValues();
-  }
-
-  @Override
-  public void handle(Request wsRequest, Response wsResponse) throws Exception {
-    ProjectRepositories data = projectDataLoader.load(ProjectDataQuery.create()
-      .setModuleKey(wsRequest.mandatoryParam(PARAM_KEY))
-      .setProfileName(wsRequest.param(PARAM_PROFILE))
-      .setIssuesMode(wsRequest.mandatoryParamAsBoolean(PARAM_PREVIEW)));
-
-    WsProjectResponse projectResponse = buildResponse(data);
-    writeProtobuf(projectResponse, wsRequest, wsResponse);
-  }
-
-  private static WsProjectResponse buildResponse(ProjectRepositories data) {
-    WsProjectResponse.Builder response = WsProjectResponse.newBuilder();
-    setLastAnalysisDate(response, data);
-    response.setTimestamp(data.timestamp());
-    response.getMutableFileDataByModuleAndPatch()
-      .putAll(buildFileDataByModuleAndPatch(data));
-    response.getMutableSettingsByModule()
-      .putAll(buildSettingsByModule(data));
-
-    return response.build();
-  }
-
-  private static void setLastAnalysisDate(WsProjectResponse.Builder response, ProjectRepositories data) {
-    if (data.lastAnalysisDate() != null) {
-      response.setLastAnalysisDate(data.lastAnalysisDate().getTime());
-    }
-  }
-
-  private static Map<String, WsProjectResponse.FileDataByPath> buildFileDataByModuleAndPatch(ProjectRepositories data) {
-    Map<String, WsProjectResponse.FileDataByPath> fileDataByModuleAndPathResponse = new HashMap<>();
-    for (Map.Entry<String, Map<String, FileData>> moduleAndFileDataByPathEntry : data.fileDataByModuleAndPath().entrySet()) {
-      fileDataByModuleAndPathResponse.put(
-        moduleAndFileDataByPathEntry.getKey(),
-        buildFileDataByPath(moduleAndFileDataByPathEntry.getValue()));
-    }
-
-    return fileDataByModuleAndPathResponse;
-  }
-
-  private static WsProjectResponse.FileDataByPath buildFileDataByPath(Map<String, FileData> fileDataByPath) {
-    WsProjectResponse.FileDataByPath.Builder response = WsProjectResponse.FileDataByPath.newBuilder();
-    Map<String, WsProjectResponse.FileData> fileDataByPathResponse = response.getMutableFileDataByPath();
-
-    for (Map.Entry<String, FileData> pathFileDataEntry : fileDataByPath.entrySet()) {
-      fileDataByPathResponse.put(
-        pathFileDataEntry.getKey(),
-        toFileDataResponse(pathFileDataEntry.getValue()));
-    }
-
-    return response.build();
-  }
-
-  private static Map<String, WsProjectResponse.Settings> buildSettingsByModule(ProjectRepositories data) {
-    Map<String, WsProjectResponse.Settings> settingsByModuleResponse = new HashMap<>();
-    for (Map.Entry<String, Map<String, String>> moduleSettingsEntry : data.settings().entrySet()) {
-      settingsByModuleResponse.put(
-        moduleSettingsEntry.getKey(),
-        toSettingsResponse(moduleSettingsEntry.getValue())
-        );
-    }
-
-    return settingsByModuleResponse;
-  }
-
-  private static WsProjectResponse.Settings toSettingsResponse(Map<String, String> settings) {
-    WsProjectResponse.Settings.Builder settingsResponse = WsProjectResponse.Settings
-      .newBuilder();
-    settingsResponse
-      .getMutableSettings()
-      .putAll(settings);
-
-    return settingsResponse.build();
-  }
-
-  private static WsProjectResponse.FileData toFileDataResponse(FileData fileData) {
-    return WsProjectResponse.FileData.newBuilder()
-      .setHash(fileData.hash())
-      .setRevision(fileData.revision())
-      .build();
-  }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java
deleted file mode 100644 (file)
index 2a0ccdd..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * 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.server.batch;
-
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import org.sonar.api.server.ServerSide;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.api.web.UserRole;
-import org.sonar.batch.protocol.input.FileData;
-import org.sonar.batch.protocol.input.ProjectRepositories;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.MyBatis;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.FilePathWithHashDto;
-import org.sonar.db.property.PropertyDto;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.user.UserSession;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Maps.newHashMap;
-import static java.lang.String.format;
-import static org.sonar.server.ws.WsUtils.checkFound;
-
-@ServerSide
-public class ProjectDataLoader {
-
-  private static final Logger LOG = Loggers.get(ProjectDataLoader.class);
-
-  private final DbClient dbClient;
-  private final UserSession userSession;
-
-  public ProjectDataLoader(DbClient dbClient, UserSession userSession) {
-    this.dbClient = dbClient;
-    this.userSession = userSession;
-  }
-
-  public ProjectRepositories load(ProjectDataQuery query) {
-    boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
-    checkPermission(query.isIssuesMode());
-
-    DbSession session = dbClient.openSession(false);
-    try {
-      ProjectRepositories data = new ProjectRepositories();
-      ComponentDto module = checkFound(dbClient.componentDao().selectByKey(session, query.getModuleKey()),
-        format("Project or module with key '%s' is not found", query.getModuleKey()));
-
-      // Scan permission is enough to analyze all projects but preview permission is limited to projects user can access
-      if (query.isIssuesMode() && !userSession.hasProjectPermissionByUuid(UserRole.USER, module.projectUuid())) {
-        throw new ForbiddenException("You're not authorized to access to project '" + module.name() + "', please contact your SonarQube administrator.");
-      }
-
-      ComponentDto project = getProject(module, session);
-      if (!project.key().equals(module.key())) {
-        addSettings(data, module.getKey(), getSettingsFromParents(module, hasScanPerm, session));
-      }
-
-      List<ComponentDto> modulesTree = dbClient.componentDao().selectEnabledDescendantModules(session, module.uuid());
-      Map<String, String> moduleUuidsByKey = moduleUuidsByKey(modulesTree);
-      Map<String, Long> moduleIdsByKey = moduleIdsByKey(modulesTree);
-
-      List<PropertyDto> modulesTreeSettings = dbClient.propertiesDao().selectEnabledDescendantModuleProperties(module.uuid(), session);
-      TreeModuleSettings treeModuleSettings = new TreeModuleSettings(moduleUuidsByKey, moduleIdsByKey, modulesTree, modulesTreeSettings);
-
-      addSettingsToChildrenModules(data, query.getModuleKey(), Maps.<String, String>newHashMap(), treeModuleSettings, hasScanPerm);
-      List<FilePathWithHashDto> files = searchFilesWithHashAndRevision(session, module);
-      addFileData(data, modulesTree, files);
-
-      // FIXME need real value but actually only used to know if there is a previous analysis in local issue tracking mode so any value is
-      // ok
-      data.setLastAnalysisDate(new Date());
-
-      return data;
-    } finally {
-      MyBatis.closeQuietly(session);
-    }
-  }
-
-  private List<FilePathWithHashDto> searchFilesWithHashAndRevision(DbSession session, ComponentDto module) {
-    return module.isRootProject() ?
-      dbClient.componentDao().selectEnabledFilesFromProject(session, module.uuid())
-      : dbClient.componentDao().selectEnabledDescendantFiles(session, module.uuid());
-  }
-
-  private ComponentDto getProject(ComponentDto module, DbSession session) {
-    if (!module.isRootProject()) {
-      return dbClient.componentDao().selectOrFailByUuid(session, module.projectUuid());
-    } else {
-      return module;
-    }
-  }
-
-  private Map<String, String> getSettingsFromParents(ComponentDto module, boolean hasScanPerm, DbSession session) {
-    List<ComponentDto> parents = newArrayList();
-    aggregateParentModules(module, parents, session);
-    Collections.reverse(parents);
-
-    Map<String, String> parentProperties = newHashMap();
-    for (ComponentDto parent : parents) {
-      parentProperties.putAll(getPropertiesMap(dbClient.propertiesDao().selectProjectProperties(session, parent.key()), hasScanPerm));
-    }
-    return parentProperties;
-  }
-
-  private void aggregateParentModules(ComponentDto component, List<ComponentDto> parents, DbSession session) {
-    String moduleUuid = component.moduleUuid();
-    if (moduleUuid != null) {
-      ComponentDto parent = dbClient.componentDao().selectOrFailByUuid(session, moduleUuid);
-      if (parent != null) {
-        parents.add(parent);
-        aggregateParentModules(parent, parents, session);
-      }
-    }
-  }
-
-  private void addSettingsToChildrenModules(ProjectRepositories ref, String moduleKey, Map<String, String> parentProperties, TreeModuleSettings treeModuleSettings,
-    boolean hasScanPerm) {
-    Map<String, String> currentParentProperties = newHashMap();
-    currentParentProperties.putAll(parentProperties);
-    currentParentProperties.putAll(getPropertiesMap(treeModuleSettings.findModuleSettings(moduleKey), hasScanPerm));
-    addSettings(ref, moduleKey, currentParentProperties);
-
-    for (ComponentDto childModule : treeModuleSettings.findChildrenModule(moduleKey)) {
-      addSettings(ref, childModule.getKey(), currentParentProperties);
-      addSettingsToChildrenModules(ref, childModule.getKey(), currentParentProperties, treeModuleSettings, hasScanPerm);
-    }
-  }
-
-  private static void addSettings(ProjectRepositories ref, String module, Map<String, String> properties) {
-    if (!properties.isEmpty()) {
-      ref.addSettings(module, properties);
-    }
-  }
-
-  private static Map<String, String> getPropertiesMap(List<PropertyDto> propertyDtos, boolean hasScanPerm) {
-    Map<String, String> properties = newHashMap();
-    for (PropertyDto propertyDto : propertyDtos) {
-      String key = propertyDto.getKey();
-      String value = propertyDto.getValue();
-      if (isPropertyAllowed(key, hasScanPerm)) {
-        properties.put(key, value);
-      }
-    }
-    return properties;
-  }
-
-  private static boolean isPropertyAllowed(String key, boolean hasScanPerm) {
-    return !key.contains(".secured") || hasScanPerm;
-  }
-
-  private static void addFileData(ProjectRepositories data, List<ComponentDto> moduleChildren, List<FilePathWithHashDto> files) {
-    Map<String, String> moduleKeysByUuid = newHashMap();
-    for (ComponentDto module : moduleChildren) {
-      moduleKeysByUuid.put(module.uuid(), module.key());
-    }
-
-    for (FilePathWithHashDto file : files) {
-      FileData fileData = new FileData(file.getSrcHash(), file.getRevision());
-      data.addFileData(moduleKeysByUuid.get(file.getModuleUuid()), file.getPath(), fileData);
-    }
-  }
-
-  private void checkPermission(boolean preview) {
-    boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
-    boolean hasPreviewPerm = userSession.hasGlobalPermission(GlobalPermissions.PREVIEW_EXECUTION);
-    if (!hasPreviewPerm && !hasScanPerm) {
-      throw new ForbiddenException(Messages.NO_PERMISSION);
-    }
-    if (!preview && !hasScanPerm) {
-      throw new ForbiddenException("You're only authorized to execute a local (preview) SonarQube analysis without pushing the results to the SonarQube server. " +
-        "Please contact your SonarQube administrator.");
-    }
-    if (preview && !hasPreviewPerm) {
-      throw new ForbiddenException("You're not authorized to execute a preview analysis. Please contact your SonarQube administrator.");
-    }
-  }
-
-  private static Map<String, String> moduleUuidsByKey(List<ComponentDto> moduleChildren) {
-    Map<String, String> moduleUuidsByKey = newHashMap();
-    for (ComponentDto componentDto : moduleChildren) {
-      moduleUuidsByKey.put(componentDto.key(), componentDto.uuid());
-    }
-    return moduleUuidsByKey;
-  }
-
-  private static Map<String, Long> moduleIdsByKey(List<ComponentDto> moduleChildren) {
-    Map<String, Long> moduleIdsByKey = newHashMap();
-    for (ComponentDto componentDto : moduleChildren) {
-      moduleIdsByKey.put(componentDto.key(), componentDto.getId());
-    }
-    return moduleIdsByKey;
-  }
-
-  private static class TreeModuleSettings {
-
-    private Map<String, Long> moduleIdsByKey;
-    private Map<String, String> moduleUuidsByKey;
-    private Multimap<Long, PropertyDto> propertiesByModuleId;
-    private Multimap<String, ComponentDto> moduleChildrenByModuleUuid;
-
-    private TreeModuleSettings(Map<String, String> moduleUuidsByKey, Map<String, Long> moduleIdsByKey, List<ComponentDto> moduleChildren,
-      List<PropertyDto> moduleChildrenSettings) {
-      this.moduleIdsByKey = moduleIdsByKey;
-      this.moduleUuidsByKey = moduleUuidsByKey;
-      propertiesByModuleId = ArrayListMultimap.create();
-      moduleChildrenByModuleUuid = ArrayListMultimap.create();
-
-      for (PropertyDto settings : moduleChildrenSettings) {
-        propertiesByModuleId.put(settings.getResourceId(), settings);
-      }
-
-      for (ComponentDto componentDto : moduleChildren) {
-        String moduleUuid = componentDto.moduleUuid();
-        if (moduleUuid != null) {
-          moduleChildrenByModuleUuid.put(moduleUuid, componentDto);
-        }
-      }
-    }
-
-    List<PropertyDto> findModuleSettings(String moduleKey) {
-      Long moduleId = moduleIdsByKey.get(moduleKey);
-      return newArrayList(propertiesByModuleId.get(moduleId));
-    }
-
-    List<ComponentDto> findChildrenModule(String moduleKey) {
-      String moduleUuid = moduleUuidsByKey.get(moduleKey);
-      return newArrayList(moduleChildrenByModuleUuid.get(moduleUuid));
-    }
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataQuery.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataQuery.java
deleted file mode 100644 (file)
index fa3e824..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.server.batch;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-public class ProjectDataQuery {
-
-  private String projectOrModuleKey;
-  private String profileName;
-  private boolean issuesMode;
-
-  private ProjectDataQuery() {
-    // No direct call
-  }
-
-  public boolean isIssuesMode() {
-    return issuesMode;
-  }
-
-  public ProjectDataQuery setIssuesMode(boolean issuesMode) {
-    this.issuesMode = issuesMode;
-    return this;
-  }
-
-  @CheckForNull
-  public String getProfileName() {
-    return profileName;
-  }
-
-  public ProjectDataQuery setProfileName(@Nullable String profileName) {
-    this.profileName = profileName;
-    return this;
-  }
-
-  public String getModuleKey() {
-    return projectOrModuleKey;
-  }
-
-  public ProjectDataQuery setModuleKey(String projectOrModuleKey) {
-    this.projectOrModuleKey = projectOrModuleKey;
-    return this;
-  }
-
-  public static ProjectDataQuery create() {
-    return new ProjectDataQuery();
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/UsersAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/UsersAction.java
deleted file mode 100644 (file)
index a4ecc63..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.server.batch;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Iterator;
-import java.util.List;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.batch.protocol.input.BatchInput;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.server.plugins.MimeTypes;
-import org.sonar.server.user.UserSession;
-import org.sonar.server.user.index.UserDoc;
-import org.sonar.server.user.index.UserIndex;
-
-public class UsersAction implements BatchWsAction {
-
-  private static final String PARAM_LOGINS = "logins";
-
-  private final UserIndex userIndex;
-  private final UserSession userSession;
-
-  public UsersAction(UserIndex userIndex, UserSession userSession) {
-    this.userIndex = userIndex;
-    this.userSession = userSession;
-  }
-
-  @Override
-  public void define(WebService.NewController controller) {
-    WebService.NewAction action = controller.createAction("users")
-      .setDescription("Return user details.")
-      .setSince("5.2")
-      .setInternal(true)
-      .setHandler(this);
-
-    action
-      .createParam(PARAM_LOGINS)
-      .setRequired(true)
-      .setDescription("A comma separated list of user logins")
-      .setExampleValue("ada.lovelace,grace.hopper");
-  }
-
-  @Override
-  public void handle(Request request, Response response) throws Exception {
-    userSession.checkGlobalPermission(GlobalPermissions.PREVIEW_EXECUTION);
-    List<String> logins = request.mandatoryParamAsStrings(PARAM_LOGINS);
-
-    response.stream().setMediaType(MimeTypes.PROTOBUF);
-    BatchInput.User.Builder userBuilder = BatchInput.User.newBuilder();
-    OutputStream output = response.stream().output();
-    try {
-      for (Iterator<UserDoc> userDocIterator = userIndex.selectUsersForBatch(logins); userDocIterator.hasNext();) {
-        handleUser(userDocIterator.next(), userBuilder, output);
-      }
-    } finally {
-      output.close();
-    }
-  }
-
-  private void handleUser(UserDoc user, BatchInput.User.Builder userBuilder, OutputStream out) {
-    userBuilder.setLogin(user.login())
-      .setName(user.name());
-    try {
-      userBuilder.build().writeDelimitedTo(out);
-    } catch (IOException e) {
-      throw new IllegalStateException("Unable to serialize user", e);
-    }
-    userBuilder.clear();
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/batch/package-info.java
deleted file mode 100644 (file)
index 9fc5842..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.
- */
-
-@ParametersAreNonnullByDefault
-package org.sonar.server.batch;
-
-import javax.annotation.ParametersAreNonnullByDefault;
index 1af4c400a596d4e311ed9bb0ce4e1b34ec701b0b..aee4aebb5ae8cf6c6e4ccc5c1485256df0888751 100644 (file)
@@ -49,7 +49,7 @@ import org.sonar.server.activity.index.ActivityIndexer;
 import org.sonar.server.activity.ws.ActivitiesWs;
 import org.sonar.server.activity.ws.ActivityMapping;
 import org.sonar.server.authentication.ws.AuthenticationWs;
-import org.sonar.server.batch.BatchWsModule;
+import org.sonar.server.scanner.ScannerWsModule;
 import org.sonar.server.charts.ChartFactory;
 import org.sonar.server.charts.DistributionAreaChart;
 import org.sonar.server.charts.DistributionBarChart;
@@ -343,7 +343,7 @@ public class PlatformLevel4 extends PlatformLevel {
       ActivityIndex.class,
 
       // batch
-      BatchWsModule.class,
+      ScannerWsModule.class,
 
       // Dashboard
       DashboardsWs.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/scanner/GlobalAction.java b/server/sonar-server/src/main/java/org/sonar/server/scanner/GlobalAction.java
new file mode 100644 (file)
index 0000000..fc9706e
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * 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.server.scanner;
+
+import org.apache.commons.io.IOUtils;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.batch.protocol.input.GlobalRepositories;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.MyBatis;
+import org.sonar.db.metric.MetricDto;
+import org.sonar.db.property.PropertiesDao;
+import org.sonar.db.property.PropertyDto;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.plugins.MimeTypes;
+import org.sonar.server.user.UserSession;
+
+public class GlobalAction implements ScannerWsAction {
+
+  private final DbClient dbClient;
+  private final PropertiesDao propertiesDao;
+  private final UserSession userSession;
+
+  public GlobalAction(DbClient dbClient, PropertiesDao propertiesDao, UserSession userSession) {
+    this.dbClient = dbClient;
+    this.propertiesDao = propertiesDao;
+    this.userSession = userSession;
+  }
+
+  @Override
+  public void define(WebService.NewController controller) {
+    controller.createAction("global")
+      .setDescription("Return metrics and global properties")
+      .setSince("4.5")
+      .setInternal(true)
+      .setHandler(this);
+  }
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+    boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
+    boolean hasPreviewPerm = userSession.hasGlobalPermission(GlobalPermissions.PREVIEW_EXECUTION);
+    if (!hasPreviewPerm && !hasScanPerm) {
+      throw new ForbiddenException(Messages.NO_PERMISSION);
+    }
+
+    DbSession session = dbClient.openSession(false);
+    try {
+      GlobalRepositories ref = new GlobalRepositories();
+      addMetrics(ref, session);
+      addSettings(ref, hasScanPerm, hasPreviewPerm, session);
+
+      response.stream().setMediaType(MimeTypes.JSON);
+      IOUtils.write(ref.toJson(), response.stream().output());
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
+  private void addMetrics(GlobalRepositories ref, DbSession session) {
+    for (MetricDto metric : dbClient.metricDao().selectEnabled(session)) {
+      ref.addMetric(
+        new org.sonar.batch.protocol.input.Metric(metric.getId(), metric.getKey(),
+          metric.getValueType(),
+          metric.getDescription(),
+          metric.getDirection(),
+          metric.getKey(),
+          metric.isQualitative(),
+          metric.isUserManaged(),
+          metric.getWorstValue(),
+          metric.getBestValue(),
+          metric.isOptimizedBestValue()));
+    }
+  }
+
+  private void addSettings(GlobalRepositories ref, boolean hasScanPerm, boolean hasPreviewPerm, DbSession session) {
+    for (PropertyDto propertyDto : propertiesDao.selectGlobalProperties(session)) {
+      String key = propertyDto.getKey();
+      String value = propertyDto.getValue();
+
+      if (isPropertyAllowed(key, hasScanPerm, hasPreviewPerm)) {
+        ref.addGlobalSetting(key, value);
+      }
+    }
+  }
+
+  private static boolean isPropertyAllowed(String key, boolean hasScanPerm, boolean hasPreviewPerm) {
+    return !key.contains(".secured") || hasScanPerm || (key.contains(".license") && hasPreviewPerm);
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/scanner/IssuesAction.java b/server/sonar-server/src/main/java/org/sonar/server/scanner/IssuesAction.java
new file mode 100644 (file)
index 0000000..445ec7c
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * 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.server.scanner;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.batch.protocol.input.BatchInput;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.MyBatis;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.issue.index.IssueDoc;
+import org.sonar.server.issue.index.IssueIndex;
+import org.sonar.server.plugins.MimeTypes;
+import org.sonar.server.user.UserSession;
+
+import static com.google.common.collect.Maps.newHashMap;
+
+public class IssuesAction implements ScannerWsAction {
+
+  private static final String PARAM_KEY = "key";
+
+  private final DbClient dbClient;
+  private final IssueIndex issueIndex;
+  private final UserSession userSession;
+  private final ComponentFinder componentFinder;
+
+  public IssuesAction(DbClient dbClient, IssueIndex issueIndex, UserSession userSession, ComponentFinder componentFinder) {
+    this.dbClient = dbClient;
+    this.issueIndex = issueIndex;
+    this.userSession = userSession;
+    this.componentFinder = componentFinder;
+  }
+
+  @Override
+  public void define(WebService.NewController controller) {
+    WebService.NewAction action = controller.createAction("issues")
+      .setDescription("Return open issues")
+      .setSince("5.1")
+      .setInternal(true)
+      .setHandler(this);
+
+    action
+      .createParam(PARAM_KEY)
+      .setRequired(true)
+      .setDescription("Project, module or file key")
+      .setExampleValue("org.codehaus.sonar:sonar");
+  }
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+    userSession.checkGlobalPermission(GlobalPermissions.PREVIEW_EXECUTION);
+    final String moduleKey = request.mandatoryParam(PARAM_KEY);
+
+    response.stream().setMediaType(MimeTypes.PROTOBUF);
+    DbSession session = dbClient.openSession(false);
+    try {
+      ComponentDto component = componentFinder.getByKey(session, moduleKey);
+      Map<String, String> keysByUUid = keysByUUid(session, component);
+
+      BatchInput.ServerIssue.Builder issueBuilder = BatchInput.ServerIssue.newBuilder();
+      for (Iterator<IssueDoc> issueDocIterator = issueIndex.selectIssuesForBatch(component); issueDocIterator.hasNext();) {
+        handleIssue(issueDocIterator.next(), issueBuilder, keysByUUid, response.stream().output());
+      }
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
+  private static void handleIssue(IssueDoc issue, BatchInput.ServerIssue.Builder issueBuilder, Map<String, String> keysByUUid, OutputStream out) {
+    issueBuilder.setKey(issue.key());
+    issueBuilder.setModuleKey(keysByUUid.get(issue.moduleUuid()));
+    String path = issue.filePath();
+    if (path != null) {
+      issueBuilder.setPath(path);
+    }
+    issueBuilder.setRuleRepository(issue.ruleKey().repository());
+    issueBuilder.setRuleKey(issue.ruleKey().rule());
+    String checksum = issue.checksum();
+    if (checksum != null) {
+      issueBuilder.setChecksum(checksum);
+    }
+    String assigneeLogin = issue.assignee();
+    if (assigneeLogin != null) {
+      issueBuilder.setAssigneeLogin(assigneeLogin);
+    }
+    Integer line = issue.line();
+    if (line != null) {
+      issueBuilder.setLine(line);
+    }
+    String message = issue.message();
+    if (message != null) {
+      issueBuilder.setMsg(message);
+    }
+    issueBuilder.setSeverity(org.sonar.batch.protocol.Constants.Severity.valueOf(issue.severity()));
+    issueBuilder.setManualSeverity(issue.isManualSeverity());
+    issueBuilder.setStatus(issue.status());
+    String resolution = issue.resolution();
+    if (resolution != null) {
+      issueBuilder.setResolution(resolution);
+    }
+    issueBuilder.setCreationDate(issue.creationDate().getTime());
+    try {
+      issueBuilder.build().writeDelimitedTo(out);
+    } catch (IOException e) {
+      throw new IllegalStateException("Unable to serialize issue", e);
+    }
+    issueBuilder.clear();
+  }
+
+  private Map<String, String> keysByUUid(DbSession session, ComponentDto component) {
+    Map<String, String> keysByUUid = newHashMap();
+    if (Scopes.PROJECT.equals(component.scope())) {
+      List<ComponentDto> modulesTree = dbClient.componentDao().selectDescendantModules(session, component.uuid());
+      for (ComponentDto componentDto : modulesTree) {
+        keysByUUid.put(componentDto.uuid(), componentDto.key());
+      }
+    } else {
+      String moduleUuid = component.moduleUuid();
+      if (moduleUuid == null) {
+        throw new IllegalArgumentException(String.format("The component '%s' has no module uuid", component.uuid()));
+      }
+      ComponentDto module = dbClient.componentDao().selectOrFailByUuid(session, moduleUuid);
+      keysByUUid.put(module.uuid(), module.key());
+    }
+    return keysByUUid;
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/scanner/Messages.java b/server/sonar-server/src/main/java/org/sonar/server/scanner/Messages.java
new file mode 100644 (file)
index 0000000..5d7f085
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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.server.scanner;
+
+public interface Messages {
+
+  String NO_PERMISSION = "You're not authorized to execute any SonarQube analysis. Please contact your SonarQube administrator.";
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/scanner/ProjectAction.java b/server/sonar-server/src/main/java/org/sonar/server/scanner/ProjectAction.java
new file mode 100644 (file)
index 0000000..c1c1233
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * 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.server.scanner;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.batch.protocol.input.FileData;
+import org.sonar.batch.protocol.input.ProjectRepositories;
+import org.sonarqube.ws.WsScanner.WsProjectResponse;
+
+import static org.sonar.server.ws.WsUtils.writeProtobuf;
+
+public class ProjectAction implements ScannerWsAction {
+
+  private static final String PARAM_KEY = "key";
+  private static final String PARAM_PROFILE = "profile";
+  private static final String PARAM_PREVIEW = "preview";
+
+  private final ProjectDataLoader projectDataLoader;
+
+  public ProjectAction(ProjectDataLoader projectDataLoader) {
+    this.projectDataLoader = projectDataLoader;
+  }
+
+  @Override
+  public void define(WebService.NewController controller) {
+    WebService.NewAction action = controller.createAction("project")
+      .setDescription("Return project repository")
+      .setSince("4.5")
+      .setInternal(true)
+      .setHandler(this);
+
+    action
+      .createParam(PARAM_KEY)
+      .setRequired(true)
+      .setDescription("Project or module key")
+      .setExampleValue("org.codehaus.sonar:sonar");
+
+    action
+      .createParam(PARAM_PROFILE)
+      .setDescription("Profile name")
+      .setExampleValue("SonarQube Way");
+
+    action
+      .createParam(PARAM_PREVIEW)
+      .setDescription("Preview mode or not")
+      .setDefaultValue(false)
+      .setBooleanPossibleValues();
+  }
+
+  @Override
+  public void handle(Request wsRequest, Response wsResponse) throws Exception {
+    ProjectRepositories data = projectDataLoader.load(ProjectDataQuery.create()
+      .setModuleKey(wsRequest.mandatoryParam(PARAM_KEY))
+      .setProfileName(wsRequest.param(PARAM_PROFILE))
+      .setIssuesMode(wsRequest.mandatoryParamAsBoolean(PARAM_PREVIEW)));
+
+    WsProjectResponse projectResponse = buildResponse(data);
+    writeProtobuf(projectResponse, wsRequest, wsResponse);
+  }
+
+  private static WsProjectResponse buildResponse(ProjectRepositories data) {
+    WsProjectResponse.Builder response = WsProjectResponse.newBuilder();
+    setLastAnalysisDate(response, data);
+    response.setTimestamp(data.timestamp());
+    response.getMutableFileDataByModuleAndPatch()
+      .putAll(buildFileDataByModuleAndPatch(data));
+    response.getMutableSettingsByModule()
+      .putAll(buildSettingsByModule(data));
+
+    return response.build();
+  }
+
+  private static void setLastAnalysisDate(WsProjectResponse.Builder response, ProjectRepositories data) {
+    if (data.lastAnalysisDate() != null) {
+      response.setLastAnalysisDate(data.lastAnalysisDate().getTime());
+    }
+  }
+
+  private static Map<String, WsProjectResponse.FileDataByPath> buildFileDataByModuleAndPatch(ProjectRepositories data) {
+    Map<String, WsProjectResponse.FileDataByPath> fileDataByModuleAndPathResponse = new HashMap<>();
+    for (Map.Entry<String, Map<String, FileData>> moduleAndFileDataByPathEntry : data.fileDataByModuleAndPath().entrySet()) {
+      fileDataByModuleAndPathResponse.put(
+        moduleAndFileDataByPathEntry.getKey(),
+        buildFileDataByPath(moduleAndFileDataByPathEntry.getValue()));
+    }
+
+    return fileDataByModuleAndPathResponse;
+  }
+
+  private static WsProjectResponse.FileDataByPath buildFileDataByPath(Map<String, FileData> fileDataByPath) {
+    WsProjectResponse.FileDataByPath.Builder response = WsProjectResponse.FileDataByPath.newBuilder();
+    Map<String, WsProjectResponse.FileData> fileDataByPathResponse = response.getMutableFileDataByPath();
+
+    for (Map.Entry<String, FileData> pathFileDataEntry : fileDataByPath.entrySet()) {
+      fileDataByPathResponse.put(
+        pathFileDataEntry.getKey(),
+        toFileDataResponse(pathFileDataEntry.getValue()));
+    }
+
+    return response.build();
+  }
+
+  private static Map<String, WsProjectResponse.Settings> buildSettingsByModule(ProjectRepositories data) {
+    Map<String, WsProjectResponse.Settings> settingsByModuleResponse = new HashMap<>();
+    for (Map.Entry<String, Map<String, String>> moduleSettingsEntry : data.settings().entrySet()) {
+      settingsByModuleResponse.put(
+        moduleSettingsEntry.getKey(),
+        toSettingsResponse(moduleSettingsEntry.getValue())
+        );
+    }
+
+    return settingsByModuleResponse;
+  }
+
+  private static WsProjectResponse.Settings toSettingsResponse(Map<String, String> settings) {
+    WsProjectResponse.Settings.Builder settingsResponse = WsProjectResponse.Settings
+      .newBuilder();
+    settingsResponse
+      .getMutableSettings()
+      .putAll(settings);
+
+    return settingsResponse.build();
+  }
+
+  private static WsProjectResponse.FileData toFileDataResponse(FileData fileData) {
+    return WsProjectResponse.FileData.newBuilder()
+      .setHash(fileData.hash())
+      .setRevision(fileData.revision())
+      .build();
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/scanner/ProjectDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/scanner/ProjectDataLoader.java
new file mode 100644 (file)
index 0000000..313022d
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * 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.server.scanner;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import org.sonar.api.server.ServerSide;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.api.web.UserRole;
+import org.sonar.batch.protocol.input.FileData;
+import org.sonar.batch.protocol.input.ProjectRepositories;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.MyBatis;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.FilePathWithHashDto;
+import org.sonar.db.property.PropertyDto;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.user.UserSession;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Maps.newHashMap;
+import static java.lang.String.format;
+import static org.sonar.server.ws.WsUtils.checkFound;
+
+@ServerSide
+public class ProjectDataLoader {
+
+  private static final Logger LOG = Loggers.get(ProjectDataLoader.class);
+
+  private final DbClient dbClient;
+  private final UserSession userSession;
+
+  public ProjectDataLoader(DbClient dbClient, UserSession userSession) {
+    this.dbClient = dbClient;
+    this.userSession = userSession;
+  }
+
+  public ProjectRepositories load(ProjectDataQuery query) {
+    boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
+    checkPermission(query.isIssuesMode());
+
+    DbSession session = dbClient.openSession(false);
+    try {
+      ProjectRepositories data = new ProjectRepositories();
+      ComponentDto module = checkFound(dbClient.componentDao().selectByKey(session, query.getModuleKey()),
+        format("Project or module with key '%s' is not found", query.getModuleKey()));
+
+      // Scan permission is enough to analyze all projects but preview permission is limited to projects user can access
+      if (query.isIssuesMode() && !userSession.hasProjectPermissionByUuid(UserRole.USER, module.projectUuid())) {
+        throw new ForbiddenException("You're not authorized to access to project '" + module.name() + "', please contact your SonarQube administrator.");
+      }
+
+      ComponentDto project = getProject(module, session);
+      if (!project.key().equals(module.key())) {
+        addSettings(data, module.getKey(), getSettingsFromParents(module, hasScanPerm, session));
+      }
+
+      List<ComponentDto> modulesTree = dbClient.componentDao().selectEnabledDescendantModules(session, module.uuid());
+      Map<String, String> moduleUuidsByKey = moduleUuidsByKey(modulesTree);
+      Map<String, Long> moduleIdsByKey = moduleIdsByKey(modulesTree);
+
+      List<PropertyDto> modulesTreeSettings = dbClient.propertiesDao().selectEnabledDescendantModuleProperties(module.uuid(), session);
+      TreeModuleSettings treeModuleSettings = new TreeModuleSettings(moduleUuidsByKey, moduleIdsByKey, modulesTree, modulesTreeSettings);
+
+      addSettingsToChildrenModules(data, query.getModuleKey(), Maps.<String, String>newHashMap(), treeModuleSettings, hasScanPerm);
+      List<FilePathWithHashDto> files = searchFilesWithHashAndRevision(session, module);
+      addFileData(data, modulesTree, files);
+
+      // FIXME need real value but actually only used to know if there is a previous analysis in local issue tracking mode so any value is
+      // ok
+      data.setLastAnalysisDate(new Date());
+
+      return data;
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
+  private List<FilePathWithHashDto> searchFilesWithHashAndRevision(DbSession session, ComponentDto module) {
+    return module.isRootProject() ?
+      dbClient.componentDao().selectEnabledFilesFromProject(session, module.uuid())
+      : dbClient.componentDao().selectEnabledDescendantFiles(session, module.uuid());
+  }
+
+  private ComponentDto getProject(ComponentDto module, DbSession session) {
+    if (!module.isRootProject()) {
+      return dbClient.componentDao().selectOrFailByUuid(session, module.projectUuid());
+    } else {
+      return module;
+    }
+  }
+
+  private Map<String, String> getSettingsFromParents(ComponentDto module, boolean hasScanPerm, DbSession session) {
+    List<ComponentDto> parents = newArrayList();
+    aggregateParentModules(module, parents, session);
+    Collections.reverse(parents);
+
+    Map<String, String> parentProperties = newHashMap();
+    for (ComponentDto parent : parents) {
+      parentProperties.putAll(getPropertiesMap(dbClient.propertiesDao().selectProjectProperties(session, parent.key()), hasScanPerm));
+    }
+    return parentProperties;
+  }
+
+  private void aggregateParentModules(ComponentDto component, List<ComponentDto> parents, DbSession session) {
+    String moduleUuid = component.moduleUuid();
+    if (moduleUuid != null) {
+      ComponentDto parent = dbClient.componentDao().selectOrFailByUuid(session, moduleUuid);
+      if (parent != null) {
+        parents.add(parent);
+        aggregateParentModules(parent, parents, session);
+      }
+    }
+  }
+
+  private void addSettingsToChildrenModules(ProjectRepositories ref, String moduleKey, Map<String, String> parentProperties, TreeModuleSettings treeModuleSettings,
+    boolean hasScanPerm) {
+    Map<String, String> currentParentProperties = newHashMap();
+    currentParentProperties.putAll(parentProperties);
+    currentParentProperties.putAll(getPropertiesMap(treeModuleSettings.findModuleSettings(moduleKey), hasScanPerm));
+    addSettings(ref, moduleKey, currentParentProperties);
+
+    for (ComponentDto childModule : treeModuleSettings.findChildrenModule(moduleKey)) {
+      addSettings(ref, childModule.getKey(), currentParentProperties);
+      addSettingsToChildrenModules(ref, childModule.getKey(), currentParentProperties, treeModuleSettings, hasScanPerm);
+    }
+  }
+
+  private static void addSettings(ProjectRepositories ref, String module, Map<String, String> properties) {
+    if (!properties.isEmpty()) {
+      ref.addSettings(module, properties);
+    }
+  }
+
+  private static Map<String, String> getPropertiesMap(List<PropertyDto> propertyDtos, boolean hasScanPerm) {
+    Map<String, String> properties = newHashMap();
+    for (PropertyDto propertyDto : propertyDtos) {
+      String key = propertyDto.getKey();
+      String value = propertyDto.getValue();
+      if (isPropertyAllowed(key, hasScanPerm)) {
+        properties.put(key, value);
+      }
+    }
+    return properties;
+  }
+
+  private static boolean isPropertyAllowed(String key, boolean hasScanPerm) {
+    return !key.contains(".secured") || hasScanPerm;
+  }
+
+  private static void addFileData(ProjectRepositories data, List<ComponentDto> moduleChildren, List<FilePathWithHashDto> files) {
+    Map<String, String> moduleKeysByUuid = newHashMap();
+    for (ComponentDto module : moduleChildren) {
+      moduleKeysByUuid.put(module.uuid(), module.key());
+    }
+
+    for (FilePathWithHashDto file : files) {
+      FileData fileData = new FileData(file.getSrcHash(), file.getRevision());
+      data.addFileData(moduleKeysByUuid.get(file.getModuleUuid()), file.getPath(), fileData);
+    }
+  }
+
+  private void checkPermission(boolean preview) {
+    boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
+    boolean hasPreviewPerm = userSession.hasGlobalPermission(GlobalPermissions.PREVIEW_EXECUTION);
+    if (!hasPreviewPerm && !hasScanPerm) {
+      throw new ForbiddenException(Messages.NO_PERMISSION);
+    }
+    if (!preview && !hasScanPerm) {
+      throw new ForbiddenException("You're only authorized to execute a local (preview) SonarQube analysis without pushing the results to the SonarQube server. " +
+        "Please contact your SonarQube administrator.");
+    }
+    if (preview && !hasPreviewPerm) {
+      throw new ForbiddenException("You're not authorized to execute a preview analysis. Please contact your SonarQube administrator.");
+    }
+  }
+
+  private static Map<String, String> moduleUuidsByKey(List<ComponentDto> moduleChildren) {
+    Map<String, String> moduleUuidsByKey = newHashMap();
+    for (ComponentDto componentDto : moduleChildren) {
+      moduleUuidsByKey.put(componentDto.key(), componentDto.uuid());
+    }
+    return moduleUuidsByKey;
+  }
+
+  private static Map<String, Long> moduleIdsByKey(List<ComponentDto> moduleChildren) {
+    Map<String, Long> moduleIdsByKey = newHashMap();
+    for (ComponentDto componentDto : moduleChildren) {
+      moduleIdsByKey.put(componentDto.key(), componentDto.getId());
+    }
+    return moduleIdsByKey;
+  }
+
+  private static class TreeModuleSettings {
+
+    private Map<String, Long> moduleIdsByKey;
+    private Map<String, String> moduleUuidsByKey;
+    private Multimap<Long, PropertyDto> propertiesByModuleId;
+    private Multimap<String, ComponentDto> moduleChildrenByModuleUuid;
+
+    private TreeModuleSettings(Map<String, String> moduleUuidsByKey, Map<String, Long> moduleIdsByKey, List<ComponentDto> moduleChildren,
+      List<PropertyDto> moduleChildrenSettings) {
+      this.moduleIdsByKey = moduleIdsByKey;
+      this.moduleUuidsByKey = moduleUuidsByKey;
+      propertiesByModuleId = ArrayListMultimap.create();
+      moduleChildrenByModuleUuid = ArrayListMultimap.create();
+
+      for (PropertyDto settings : moduleChildrenSettings) {
+        propertiesByModuleId.put(settings.getResourceId(), settings);
+      }
+
+      for (ComponentDto componentDto : moduleChildren) {
+        String moduleUuid = componentDto.moduleUuid();
+        if (moduleUuid != null) {
+          moduleChildrenByModuleUuid.put(moduleUuid, componentDto);
+        }
+      }
+    }
+
+    List<PropertyDto> findModuleSettings(String moduleKey) {
+      Long moduleId = moduleIdsByKey.get(moduleKey);
+      return newArrayList(propertiesByModuleId.get(moduleId));
+    }
+
+    List<ComponentDto> findChildrenModule(String moduleKey) {
+      String moduleUuid = moduleUuidsByKey.get(moduleKey);
+      return newArrayList(moduleChildrenByModuleUuid.get(moduleUuid));
+    }
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/scanner/ProjectDataQuery.java b/server/sonar-server/src/main/java/org/sonar/server/scanner/ProjectDataQuery.java
new file mode 100644 (file)
index 0000000..de13aef
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 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.server.scanner;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+public class ProjectDataQuery {
+
+  private String projectOrModuleKey;
+  private String profileName;
+  private boolean issuesMode;
+
+  private ProjectDataQuery() {
+    // No direct call
+  }
+
+  public boolean isIssuesMode() {
+    return issuesMode;
+  }
+
+  public ProjectDataQuery setIssuesMode(boolean issuesMode) {
+    this.issuesMode = issuesMode;
+    return this;
+  }
+
+  @CheckForNull
+  public String getProfileName() {
+    return profileName;
+  }
+
+  public ProjectDataQuery setProfileName(@Nullable String profileName) {
+    this.profileName = profileName;
+    return this;
+  }
+
+  public String getModuleKey() {
+    return projectOrModuleKey;
+  }
+
+  public ProjectDataQuery setModuleKey(String projectOrModuleKey) {
+    this.projectOrModuleKey = projectOrModuleKey;
+    return this;
+  }
+
+  public static ProjectDataQuery create() {
+    return new ProjectDataQuery();
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/scanner/ScannerIndex.java b/server/sonar-server/src/main/java/org/sonar/server/scanner/ScannerIndex.java
new file mode 100644 (file)
index 0000000..d9f82d2
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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.server.scanner;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.FileFilterUtils;
+import org.apache.commons.io.filefilter.HiddenFileFilter;
+import org.apache.commons.lang.CharUtils;
+import org.apache.commons.lang.StringUtils;
+import org.picocontainer.Startable;
+import org.sonar.api.server.ServerSide;
+import org.sonar.api.platform.Server;
+import org.sonar.home.cache.FileHashes;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+
+/**
+ * JAR files to be downloaded by sonar-runner.
+ */
+@ServerSide
+public class ScannerIndex implements Startable {
+
+  private final Server server;
+  private String index;
+  private File batchDir;
+
+  public ScannerIndex(Server server) {
+    this.server = server;
+  }
+
+  @Override
+  public void start() {
+    StringBuilder sb = new StringBuilder();
+    batchDir = new File(server.getRootDir(), "lib/batch");
+    if (batchDir.exists()) {
+      Collection<File> files = FileUtils.listFiles(batchDir, HiddenFileFilter.VISIBLE, FileFilterUtils.directoryFileFilter());
+      for (File file : files) {
+        String filename = file.getName();
+        if (StringUtils.endsWith(filename, ".jar")) {
+          sb.append(filename).append('|').append(new FileHashes().of(file)).append(CharUtils.LF);
+        }
+      }
+    }
+    this.index = sb.toString();
+  }
+
+  @Override
+  public void stop() {
+    // Nothing to do
+  }
+
+  String getIndex() {
+    return index;
+  }
+
+  File getFile(String filename) {
+    try {
+      File input = new File(batchDir, filename);
+      if (!input.exists() || !FileUtils.directoryContains(batchDir, input)) {
+        throw new IllegalArgumentException("Bad filename: " + filename);
+      }
+      return input;
+
+    } catch (IOException e) {
+      throw new IllegalStateException("Can get file " + filename, e);
+    }
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/scanner/ScannerWs.java b/server/sonar-server/src/main/java/org/sonar/server/scanner/ScannerWs.java
new file mode 100644 (file)
index 0000000..b8d4c4c
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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.server.scanner;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+
+import java.io.IOException;
+
+public class ScannerWs implements WebService {
+
+  public static final String API_ENDPOINT = "scanner";
+
+  private final ScannerIndex scannerIndex;
+  private final ScannerWsAction[] actions;
+
+  public ScannerWs(ScannerIndex scannerIndex, ScannerWsAction... actions) {
+    this.scannerIndex = scannerIndex;
+    this.actions = actions;
+  }
+
+  @Override
+  public void define(Context context) {
+    NewController controller = context.createController(API_ENDPOINT)
+      .setSince("4.4")
+      .setDescription("Get JAR files and referentials for batch");
+
+    defineIndexAction(controller);
+    defineFileAction(controller);
+    for (ScannerWsAction action : actions) {
+      action.define(controller);
+    }
+
+    controller.done();
+  }
+
+  private void defineIndexAction(NewController controller) {
+    controller.createAction("index")
+      .setInternal(true)
+      .setDescription("List the JAR files to be downloaded by source analyzer")
+      .setHandler(new RequestHandler() {
+        @Override
+        public void handle(Request request, Response response) {
+          try {
+            response.stream().setMediaType("text/plain");
+            IOUtils.write(scannerIndex.getIndex(), response.stream().output());
+          } catch (IOException e) {
+            throw new IllegalStateException(e);
+          }
+        }
+      })
+      .setResponseExample(getClass().getResource("example-batch-index.txt"));
+  }
+
+  private void defineFileAction(NewController controller) {
+    controller.createAction("file")
+      .setInternal(true)
+      .setDescription("Download a JAR file required by source analyzer")
+      .setHandler(new RequestHandler() {
+        @Override
+        public void handle(Request request, Response response) {
+          String filename = request.mandatoryParam("name");
+          try {
+            response.stream().setMediaType("application/java-archive");
+            FileUtils.copyFile(scannerIndex.getFile(filename), response.stream().output());
+          } catch (IOException e) {
+            throw new IllegalStateException(e);
+          }
+        }
+      })
+      .createParam("name")
+      .setDescription("File name")
+      .setExampleValue("batch-library-2.3.jar");
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/scanner/ScannerWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/scanner/ScannerWsAction.java
new file mode 100644 (file)
index 0000000..2df2a0f
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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.server.scanner;
+
+import org.sonar.server.ws.WsAction;
+
+public interface ScannerWsAction extends WsAction {
+  // Marker interface
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/scanner/ScannerWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/scanner/ScannerWsModule.java
new file mode 100644 (file)
index 0000000..cc2b3be
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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.server.scanner;
+
+import org.sonar.core.platform.Module;
+
+public class ScannerWsModule extends Module {
+  @Override
+  protected void configureModule() {
+    add(
+      ScannerIndex.class,
+      GlobalAction.class,
+      ProjectAction.class,
+      ProjectDataLoader.class,
+      IssuesAction.class,
+      UsersAction.class,
+      ScannerWs.class);
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/scanner/UsersAction.java b/server/sonar-server/src/main/java/org/sonar/server/scanner/UsersAction.java
new file mode 100644 (file)
index 0000000..b738bf2
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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.server.scanner;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.List;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.batch.protocol.input.BatchInput;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.server.plugins.MimeTypes;
+import org.sonar.server.user.UserSession;
+import org.sonar.server.user.index.UserDoc;
+import org.sonar.server.user.index.UserIndex;
+
+public class UsersAction implements ScannerWsAction {
+
+  private static final String PARAM_LOGINS = "logins";
+
+  private final UserIndex userIndex;
+  private final UserSession userSession;
+
+  public UsersAction(UserIndex userIndex, UserSession userSession) {
+    this.userIndex = userIndex;
+    this.userSession = userSession;
+  }
+
+  @Override
+  public void define(WebService.NewController controller) {
+    WebService.NewAction action = controller.createAction("users")
+      .setDescription("Return user details.")
+      .setSince("5.2")
+      .setInternal(true)
+      .setHandler(this);
+
+    action
+      .createParam(PARAM_LOGINS)
+      .setRequired(true)
+      .setDescription("A comma separated list of user logins")
+      .setExampleValue("ada.lovelace,grace.hopper");
+  }
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+    userSession.checkGlobalPermission(GlobalPermissions.PREVIEW_EXECUTION);
+    List<String> logins = request.mandatoryParamAsStrings(PARAM_LOGINS);
+
+    response.stream().setMediaType(MimeTypes.PROTOBUF);
+    BatchInput.User.Builder userBuilder = BatchInput.User.newBuilder();
+    OutputStream output = response.stream().output();
+    try {
+      for (Iterator<UserDoc> userDocIterator = userIndex.selectUsersForBatch(logins); userDocIterator.hasNext();) {
+        handleUser(userDocIterator.next(), userBuilder, output);
+      }
+    } finally {
+      output.close();
+    }
+  }
+
+  private void handleUser(UserDoc user, BatchInput.User.Builder userBuilder, OutputStream out) {
+    userBuilder.setLogin(user.login())
+      .setName(user.name());
+    try {
+      userBuilder.build().writeDelimitedTo(out);
+    } catch (IOException e) {
+      throw new IllegalStateException("Unable to serialize user", e);
+    }
+    userBuilder.clear();
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/scanner/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/scanner/package-info.java
new file mode 100644 (file)
index 0000000..81945a8
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.server.scanner;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/BatchIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/BatchIndexTest.java
deleted file mode 100644 (file)
index 884524c..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.server.batch;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.CharUtils;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.platform.Server;
-
-import java.io.File;
-import java.io.IOException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class BatchIndexTest {
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  File jar;
-
-  Server server = mock(Server.class);
-
-  @Before
-  public void prepare_fs() throws IOException {
-    File rootDir = temp.newFolder();
-    when(server.getRootDir()).thenReturn(rootDir);
-
-    File batchDir = new File(rootDir, "lib/batch");
-    FileUtils.forceMkdir(batchDir);
-    jar = new File(batchDir, "sonar-batch.jar");
-    FileUtils.writeStringToFile(new File(batchDir, "sonar-batch.jar"), "foo");
-  }
-
-  @Test
-  public void get_index() {
-    BatchIndex batchIndex = new BatchIndex(server);
-    batchIndex.start();
-
-    String index = batchIndex.getIndex();
-    assertThat(index).isEqualTo("sonar-batch.jar|acbd18db4cc2f85cedef654fccc4a4d8" + CharUtils.LF);
-
-    batchIndex.stop();
-  }
-
-  @Test
-  public void get_file() {
-    BatchIndex batchIndex = new BatchIndex(server);
-    batchIndex.start();
-
-    File file = batchIndex.getFile("sonar-batch.jar");
-    assertThat(file).isEqualTo(jar);
-  }
-
-  /**
-   * Do not allow to download files located outside the directory lib/batch, for example
-   * /etc/passwd
-   */
-  @Test
-  public void check_location_of_file() {
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage("Bad filename: ../sonar-batch.jar");
-
-    BatchIndex batchIndex = new BatchIndex(server);
-    batchIndex.start();
-
-    batchIndex.getFile("../sonar-batch.jar");
-  }
-
-  @Test
-  public void file_does_not_exist() {
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage("Bad filename: other.jar");
-
-    BatchIndex batchIndex = new BatchIndex(server);
-    batchIndex.start();
-
-    batchIndex.getFile("other.jar");
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsModuleTest.java
deleted file mode 100644 (file)
index 997ac69..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.server.batch;
-
-import org.junit.Test;
-import org.sonar.core.platform.ComponentContainer;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class BatchWsModuleTest {
-  @Test
-  public void verify_count_of_added_components() {
-    ComponentContainer container = new ComponentContainer();
-    new BatchWsModule().configure(container);
-    assertThat(container.size()).isEqualTo(9);
-  }
-
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/BatchWsTest.java
deleted file mode 100644 (file)
index c1f2084..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.server.batch;
-
-import java.io.File;
-import org.apache.commons.io.FileUtils;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.db.property.PropertiesDao;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.issue.index.IssueIndex;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.WsTester;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-@RunWith(MockitoJUnitRunner.class)
-public class BatchWsTest {
-  @Rule
-  public UserSessionRule userSessionRule = UserSessionRule.standalone();
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  @Mock
-  BatchIndex batchIndex;
-
-  WsTester tester;
-
-  @Before
-  public void before() {
-    tester = new WsTester(new BatchWs(batchIndex,
-      new GlobalAction(mock(DbClient.class), mock(PropertiesDao.class), userSessionRule),
-      new ProjectAction(mock(ProjectDataLoader.class)),
-      new IssuesAction(mock(DbClient.class), mock(IssueIndex.class), userSessionRule, mock(ComponentFinder.class))));
-  }
-
-  @Test
-  public void download_index() throws Exception {
-    when(batchIndex.getIndex()).thenReturn("sonar-batch.jar|acbd18db4cc2f85cedef654fccc4a4d8");
-
-    String index = tester.newGetRequest("batch", "index").execute().outputAsString();
-    assertThat(index).isEqualTo("sonar-batch.jar|acbd18db4cc2f85cedef654fccc4a4d8");
-  }
-
-  @Test
-  public void download_file() throws Exception {
-    String filename = "sonar-batch.jar";
-
-    File file = temp.newFile(filename);
-    FileUtils.writeStringToFile(file, "foo");
-    when(batchIndex.getFile(filename)).thenReturn(file);
-
-    String jar = tester.newGetRequest("batch", "file").setParam("name", filename).execute().outputAsString();
-    assertThat(jar).isEqualTo("foo");
-  }
-
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/GlobalActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/GlobalActionTest.java
deleted file mode 100644 (file)
index 31ebee4..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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.server.batch;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.metric.MetricDao;
-import org.sonar.db.metric.MetricDto;
-import org.sonar.db.property.PropertiesDao;
-import org.sonar.db.property.PropertyDto;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.WsTester;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-@RunWith(MockitoJUnitRunner.class)
-public class GlobalActionTest {
-  @Rule
-  public UserSessionRule userSessionRule = UserSessionRule.standalone();
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  @Mock
-  DbSession session;
-
-  @Mock
-  MetricDao metricDao;
-
-  @Mock
-  PropertiesDao propertiesDao;
-
-  WsTester tester;
-
-  @Before
-  public void setUp() {
-    DbClient dbClient = mock(DbClient.class);
-    when(dbClient.openSession(false)).thenReturn(session);
-    when(dbClient.metricDao()).thenReturn(metricDao);
-
-    tester = new WsTester(new BatchWs(mock(BatchIndex.class), new GlobalAction(dbClient, propertiesDao, userSessionRule)));
-  }
-
-  @Test
-  public void return_metrics() throws Exception {
-    userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.PREVIEW_EXECUTION);
-
-    when(metricDao.selectEnabled(session)).thenReturn(newArrayList(
-      new MetricDto().setId(1).setKey("coverage").setDescription("Coverage by unit tests").setValueType("PERCENT").setQualitative(true)
-        .setWorstValue(0d).setBestValue(100d).setOptimizedBestValue(false).setDirection(1).setEnabled(true)
-      ));
-
-    WsTester.TestRequest request = tester.newGetRequest("batch", "global");
-    request.execute().assertJson(getClass(), "return_global_referentials.json");
-  }
-
-  @Test
-  public void return_global_settings() throws Exception {
-    userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.PREVIEW_EXECUTION);
-
-    when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList(
-      new PropertyDto().setKey("foo").setValue("bar"),
-      new PropertyDto().setKey("foo.secured").setValue("1234"),
-      new PropertyDto().setKey("foo.license.secured").setValue("5678")
-      ));
-
-    WsTester.TestRequest request = tester.newGetRequest("batch", "global");
-    request.execute().assertJson(getClass(), "return_global_settings.json");
-  }
-
-  @Test
-  public void return_only_license_settings_without_scan_but_with_preview_permission() throws Exception {
-    userSessionRule.setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
-
-    when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList(
-      new PropertyDto().setKey("foo").setValue("bar"),
-      new PropertyDto().setKey("foo.secured").setValue("1234"),
-      new PropertyDto().setKey("foo.license.secured").setValue("5678")
-      ));
-
-    WsTester.TestRequest request = tester.newGetRequest("batch", "global");
-    request.execute().assertJson(getClass(), "return_only_license_settings_without_scan_but_with_preview_permission.json");
-  }
-
-  @Test
-  public void access_forbidden_without_scan_and_preview_permission() throws Exception {
-    userSessionRule.setGlobalPermissions();
-
-    when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList(
-      new PropertyDto().setKey("foo").setValue("bar"),
-      new PropertyDto().setKey("foo.secured").setValue("1234"),
-      new PropertyDto().setKey("foo.license.secured").setValue("5678")
-      ));
-
-    thrown.expect(ForbiddenException.class);
-
-    tester.newGetRequest("batch", "global").execute();
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java
deleted file mode 100644 (file)
index 67950cb..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * 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.server.batch;
-
-import java.io.ByteArrayInputStream;
-import java.util.Arrays;
-import javax.annotation.Nullable;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.sonar.api.config.Settings;
-import org.sonar.api.platform.Server;
-import org.sonar.api.security.DefaultGroups;
-import org.sonar.api.utils.System2;
-import org.sonar.batch.protocol.Constants.Severity;
-import org.sonar.batch.protocol.input.BatchInput.ServerIssue;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.db.component.ComponentTesting;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.issue.IssueTesting;
-import org.sonar.server.issue.index.IssueAuthorizationDao;
-import org.sonar.server.issue.index.IssueAuthorizationIndexer;
-import org.sonar.server.issue.index.IssueDoc;
-import org.sonar.server.issue.index.IssueIndex;
-import org.sonar.server.issue.index.IssueIndexDefinition;
-import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.WsTester;
-import org.sonar.test.DbTests;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-@Category(DbTests.class)
-public class IssuesActionTest {
-
-  private final static String PROJECT_KEY = "struts";
-  private final static String MODULE_KEY = "struts-core";
-  private final static String FILE_KEY = "Action.java";
-
-  @Rule
-  public DbTester db = DbTester.create(System2.INSTANCE);
-
-  @ClassRule
-  public static EsTester es = new EsTester().addDefinitions(new IssueIndexDefinition(new Settings()));
-
-  @Rule
-  public UserSessionRule userSessionRule = UserSessionRule.standalone();
-
-  IssueIndex issueIndex;
-  IssueIndexer issueIndexer;
-  IssueAuthorizationIndexer issueAuthorizationIndexer;
-
-  WsTester tester;
-
-  IssuesAction issuesAction;
-
-  @Before
-  public void before() {
-    db.truncateTables();
-    es.truncateIndices();
-
-    issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSessionRule);
-    issueIndexer = new IssueIndexer(null, es.client());
-    issueAuthorizationIndexer = new IssueAuthorizationIndexer(null, es.client());
-    issuesAction = new IssuesAction(db.getDbClient(), issueIndex, userSessionRule, new ComponentFinder(db.getDbClient()));
-
-    tester = new WsTester(new BatchWs(new BatchIndex(mock(Server.class)), issuesAction));
-  }
-
-  @Test
-  public void return_minimal_fields() throws Exception {
-    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
-    ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey(MODULE_KEY);
-    ComponentDto file = ComponentTesting.newFileDto(module, "CDEF").setKey(FILE_KEY).setPath(null);
-    db.getDbClient().componentDao().insert(db.getSession(), project, module, file);
-    db.getSession().commit();
-
-    indexIssues(IssueTesting.newDoc("EFGH", file)
-      .setRuleKey("squid:AvoidCycle")
-      .setSeverity("BLOCKER")
-      .setStatus("RESOLVED")
-      .setResolution(null)
-      .setManualSeverity(false)
-      .setMessage(null)
-      .setLine(null)
-      .setChecksum(null)
-      .setAssignee(null));
-
-    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
-
-    WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", PROJECT_KEY);
-
-    ServerIssue serverIssue = ServerIssue.parseDelimitedFrom(new ByteArrayInputStream(request.execute().output()));
-    assertThat(serverIssue.getKey()).isEqualTo("EFGH");
-    assertThat(serverIssue.getModuleKey()).isEqualTo(MODULE_KEY);
-    assertThat(serverIssue.hasPath()).isFalse();
-    assertThat(serverIssue.getRuleRepository()).isEqualTo("squid");
-    assertThat(serverIssue.getRuleKey()).isEqualTo("AvoidCycle");
-    assertThat(serverIssue.hasLine()).isFalse();
-    assertThat(serverIssue.hasMsg()).isFalse();
-    assertThat(serverIssue.hasResolution()).isFalse();
-    assertThat(serverIssue.getStatus()).isEqualTo("RESOLVED");
-    assertThat(serverIssue.getSeverity()).isEqualTo(Severity.BLOCKER);
-    assertThat(serverIssue.getManualSeverity()).isFalse();
-    assertThat(serverIssue.hasChecksum()).isFalse();
-    assertThat(serverIssue.hasAssigneeLogin()).isFalse();
-  }
-
-  @Test
-  public void issues_from_project() throws Exception {
-    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
-    ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey(MODULE_KEY);
-    ComponentDto file = ComponentTesting.newFileDto(module, "CDEF").setKey(FILE_KEY).setPath("src/org/struts/Action.java");
-    db.getDbClient().componentDao().insert(db.getSession(), project, module, file);
-    db.getSession().commit();
-
-    indexIssues(IssueTesting.newDoc("EFGH", file)
-      .setRuleKey("squid:AvoidCycle")
-      .setSeverity("BLOCKER")
-      .setStatus("RESOLVED")
-      .setResolution("FALSE-POSITIVE")
-      .setManualSeverity(false)
-      .setMessage("Do not use this method")
-      .setLine(200)
-      .setChecksum("123456")
-      .setAssignee("john"));
-
-    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
-
-    WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", PROJECT_KEY);
-
-    ServerIssue serverIssue = ServerIssue.parseDelimitedFrom(new ByteArrayInputStream(request.execute().output()));
-    assertThat(serverIssue.getKey()).isEqualTo("EFGH");
-    assertThat(serverIssue.getModuleKey()).isEqualTo(MODULE_KEY);
-    assertThat(serverIssue.getPath()).isEqualTo("src/org/struts/Action.java");
-    assertThat(serverIssue.getRuleRepository()).isEqualTo("squid");
-    assertThat(serverIssue.getRuleKey()).isEqualTo("AvoidCycle");
-    assertThat(serverIssue.getLine()).isEqualTo(200);
-    assertThat(serverIssue.getMsg()).isEqualTo("Do not use this method");
-    assertThat(serverIssue.getResolution()).isEqualTo("FALSE-POSITIVE");
-    assertThat(serverIssue.getStatus()).isEqualTo("RESOLVED");
-    assertThat(serverIssue.getSeverity()).isEqualTo(Severity.BLOCKER);
-    assertThat(serverIssue.getManualSeverity()).isFalse();
-    assertThat(serverIssue.getChecksum()).isEqualTo("123456");
-    assertThat(serverIssue.getAssigneeLogin()).isEqualTo("john");
-  }
-
-  @Test
-  public void issues_from_module() throws Exception {
-    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
-    ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey(MODULE_KEY);
-    ComponentDto file = ComponentTesting.newFileDto(module, "CDEF").setKey(FILE_KEY).setPath("src/org/struts/Action.java");
-    db.getDbClient().componentDao().insert(db.getSession(), project, module, file);
-    db.getSession().commit();
-
-    indexIssues(IssueTesting.newDoc("EFGH", file)
-      .setRuleKey("squid:AvoidCycle")
-      .setSeverity("BLOCKER")
-      .setStatus("RESOLVED")
-      .setResolution("FALSE-POSITIVE")
-      .setManualSeverity(false)
-      .setMessage("Do not use this method")
-      .setLine(200)
-      .setChecksum("123456")
-      .setAssignee("john"));
-
-    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
-
-    WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", MODULE_KEY);
-    ServerIssue serverIssue = ServerIssue.parseDelimitedFrom(new ByteArrayInputStream(request.execute().output()));
-    assertThat(serverIssue.getKey()).isEqualTo("EFGH");
-    assertThat(serverIssue.getModuleKey()).isEqualTo(MODULE_KEY);
-    assertThat(serverIssue.getPath()).isEqualTo("src/org/struts/Action.java");
-    assertThat(serverIssue.getRuleRepository()).isEqualTo("squid");
-    assertThat(serverIssue.getRuleKey()).isEqualTo("AvoidCycle");
-    assertThat(serverIssue.getLine()).isEqualTo(200);
-    assertThat(serverIssue.getMsg()).isEqualTo("Do not use this method");
-    assertThat(serverIssue.getResolution()).isEqualTo("FALSE-POSITIVE");
-    assertThat(serverIssue.getStatus()).isEqualTo("RESOLVED");
-    assertThat(serverIssue.getSeverity()).isEqualTo(Severity.BLOCKER);
-    assertThat(serverIssue.getManualSeverity()).isFalse();
-    assertThat(serverIssue.getChecksum()).isEqualTo("123456");
-    assertThat(serverIssue.getAssigneeLogin()).isEqualTo("john");
-  }
-
-  @Test
-  public void issues_from_file() throws Exception {
-    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
-    ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey(MODULE_KEY);
-    ComponentDto file = ComponentTesting.newFileDto(module, "CDEF").setKey(FILE_KEY).setPath("src/org/struts/Action.java");
-    db.getDbClient().componentDao().insert(db.getSession(), project, module, file);
-    db.getSession().commit();
-
-    indexIssues(IssueTesting.newDoc("EFGH", file)
-      .setRuleKey("squid:AvoidCycle")
-      .setSeverity("BLOCKER")
-      .setStatus("RESOLVED")
-      .setResolution("FALSE-POSITIVE")
-      .setManualSeverity(false)
-      .setMessage("Do not use this method")
-      .setLine(200)
-      .setChecksum("123456")
-      .setAssignee("john"));
-
-    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
-
-    WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", FILE_KEY);
-    ServerIssue serverIssue = ServerIssue.parseDelimitedFrom(new ByteArrayInputStream(request.execute().output()));
-    assertThat(serverIssue.getKey()).isEqualTo("EFGH");
-    assertThat(serverIssue.getModuleKey()).isEqualTo(MODULE_KEY);
-    assertThat(serverIssue.getPath()).isEqualTo("src/org/struts/Action.java");
-    assertThat(serverIssue.getRuleRepository()).isEqualTo("squid");
-    assertThat(serverIssue.getRuleKey()).isEqualTo("AvoidCycle");
-    assertThat(serverIssue.getLine()).isEqualTo(200);
-    assertThat(serverIssue.getMsg()).isEqualTo("Do not use this method");
-    assertThat(serverIssue.getResolution()).isEqualTo("FALSE-POSITIVE");
-    assertThat(serverIssue.getStatus()).isEqualTo("RESOLVED");
-    assertThat(serverIssue.getSeverity()).isEqualTo(Severity.BLOCKER);
-    assertThat(serverIssue.getManualSeverity()).isFalse();
-    assertThat(serverIssue.getChecksum()).isEqualTo("123456");
-    assertThat(serverIssue.getAssigneeLogin()).isEqualTo("john");
-  }
-
-  @Test
-  public void issues_attached_on_module() throws Exception {
-    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
-    ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey(MODULE_KEY);
-    db.getDbClient().componentDao().insert(db.getSession(), project, module);
-    db.getSession().commit();
-
-    indexIssues(IssueTesting.newDoc("EFGH", module)
-      .setRuleKey("squid:AvoidCycle")
-      .setSeverity("BLOCKER")
-      .setStatus("RESOLVED")
-      .setResolution("FALSE-POSITIVE")
-      .setManualSeverity(false)
-      .setMessage("Do not use this method")
-      .setLine(200)
-      .setChecksum("123456")
-      .setAssignee("john"));
-
-    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
-
-    WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", MODULE_KEY);
-    ServerIssue previousIssue = ServerIssue.parseDelimitedFrom(new ByteArrayInputStream(request.execute().output()));
-    assertThat(previousIssue.getKey()).isEqualTo("EFGH");
-    assertThat(previousIssue.getModuleKey()).isEqualTo(MODULE_KEY);
-    assertThat(previousIssue.hasPath()).isFalse();
-    assertThat(previousIssue.getRuleRepository()).isEqualTo("squid");
-    assertThat(previousIssue.getRuleKey()).isEqualTo("AvoidCycle");
-    assertThat(previousIssue.getLine()).isEqualTo(200);
-    assertThat(previousIssue.getMsg()).isEqualTo("Do not use this method");
-    assertThat(previousIssue.getResolution()).isEqualTo("FALSE-POSITIVE");
-    assertThat(previousIssue.getStatus()).isEqualTo("RESOLVED");
-    assertThat(previousIssue.getSeverity()).isEqualTo(Severity.BLOCKER);
-    assertThat(previousIssue.getManualSeverity()).isFalse();
-    assertThat(previousIssue.getChecksum()).isEqualTo("123456");
-    assertThat(previousIssue.getAssigneeLogin()).isEqualTo("john");
-  }
-
-  @Test
-  public void project_issues_attached_file_on_removed_module() throws Exception {
-    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
-    // File and module are removed
-    ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey(MODULE_KEY).setEnabled(false);
-    ComponentDto file = ComponentTesting.newFileDto(module, "CDEF").setKey(FILE_KEY).setPath("src/org/struts/Action.java").setEnabled(false);
-    db.getDbClient().componentDao().insert(db.getSession(), project, module, file);
-    db.getSession().commit();
-
-    indexIssues(IssueTesting.newDoc("EFGH", file)
-      .setRuleKey("squid:AvoidCycle")
-      .setSeverity("BLOCKER")
-      .setStatus("RESOLVED")
-      .setResolution("FALSE-POSITIVE")
-      .setManualSeverity(false)
-      .setMessage("Do not use this method")
-      .setLine(200)
-      .setChecksum("123456")
-      .setAssignee("john"));
-
-    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
-
-    WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", PROJECT_KEY);
-    ServerIssue serverIssue = ServerIssue.parseDelimitedFrom(new ByteArrayInputStream(request.execute().output()));
-    assertThat(serverIssue.getKey()).isEqualTo("EFGH");
-    // Module key of removed file should be returned
-    assertThat(serverIssue.getModuleKey()).isEqualTo(MODULE_KEY);
-  }
-
-  @Test(expected = ForbiddenException.class)
-  public void fail_without_preview_permission() throws Exception {
-    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PROVISIONING);
-
-    WsTester.TestRequest request = tester.newGetRequest("batch", "issues").setParam("key", PROJECT_KEY);
-    request.execute();
-  }
-
-  private void indexIssues(IssueDoc... issues) {
-    issueIndexer.index(Arrays.asList(issues).iterator());
-    for (IssueDoc issue : issues) {
-      addIssueAuthorization(issue.projectUuid(), DefaultGroups.ANYONE, null);
-    }
-  }
-
-  private void addIssueAuthorization(String projectUuid, @Nullable String group, @Nullable String user) {
-    issueAuthorizationIndexer.index(newArrayList(new IssueAuthorizationDao.Dto(projectUuid, 1).addGroup(group).addUser(user)));
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java
deleted file mode 100644 (file)
index 372118e..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.server.batch;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.sonar.batch.protocol.input.ProjectRepositories;
-import org.sonar.server.ws.WsTester;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ProjectActionTest {
-
-  ProjectDataLoader projectDataLoader = mock(ProjectDataLoader.class);
-
-  WsTester tester;
-
-  @Before
-  public void setUp() {
-    tester = new WsTester(new BatchWs(mock(BatchIndex.class), new ProjectAction(projectDataLoader)));
-  }
-
-  @Test
-  public void project_referentials() throws Exception {
-    String projectKey = "org.codehaus.sonar:sonar";
-
-    ProjectRepositories projectReferentials = mock(ProjectRepositories.class);
-    when(projectReferentials.toJson()).thenReturn("{\"settingsByModule\": {}}");
-
-    ArgumentCaptor<ProjectDataQuery> queryArgumentCaptor = ArgumentCaptor.forClass(ProjectDataQuery.class);
-    when(projectDataLoader.load(queryArgumentCaptor.capture())).thenReturn(projectReferentials);
-
-    WsTester.TestRequest request = tester.newGetRequest("batch", "project")
-      .setParam("key", projectKey)
-      .setParam("profile", "Default")
-      .setParam("preview", "false");
-    request.execute().assertJson("{\"settingsByModule\": {}}");
-
-    assertThat(queryArgumentCaptor.getValue().getModuleKey()).isEqualTo(projectKey);
-    assertThat(queryArgumentCaptor.getValue().getProfileName()).isEqualTo("Default");
-    assertThat(queryArgumentCaptor.getValue().isIssuesMode()).isFalse();
-  }
-
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderMediumTest.java
deleted file mode 100644 (file)
index 8498f3f..0000000
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * 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.server.batch;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.Date;
-import java.util.Map;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.web.UserRole;
-import org.sonar.batch.protocol.input.FileData;
-import org.sonar.batch.protocol.input.ProjectRepositories;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
-import org.sonar.db.property.PropertyDto;
-import org.sonar.db.qualityprofile.QualityProfileDto;
-import org.sonar.db.source.FileSourceDao;
-import org.sonar.db.source.FileSourceDto;
-import org.sonar.db.source.FileSourceDto.Type;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.qualityprofile.QProfileName;
-import org.sonar.server.tester.ServerTester;
-import org.sonar.server.tester.UserSessionRule;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-import static org.sonar.api.utils.DateUtils.formatDateTime;
-import static org.sonar.server.qualityprofile.QProfileTesting.newQProfileDto;
-
-public class ProjectDataLoaderMediumTest {
-
-  @ClassRule
-  public static ServerTester tester = new ServerTester().addXoo();
-
-  @Rule
-  public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);
-
-  DbSession dbSession;
-
-  ProjectDataLoader loader;
-
-  @Before
-  public void before() {
-    tester.clearDbAndIndexes();
-    dbSession = tester.get(DbClient.class).openSession(false);
-    loader = tester.get(ProjectDataLoader.class);
-  }
-
-  @After
-  public void after() {
-    dbSession.close();
-  }
-
-  @Test
-  public void return_project_settings() {
-    ComponentDto project = ComponentTesting.newProjectDto();
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())
-      );
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())
-      );
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
-    Map<String, String> projectSettings = ref.settings(project.key());
-    assertThat(projectSettings).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"
-      ));
-  }
-
-  @Test
-  public void not_returned_secured_settings_with_only_preview_permission() {
-    ComponentDto project = ComponentTesting.newProjectDto();
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION).addProjectUuidPermissions(UserRole.USER, project.uuid());
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())
-      );
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())
-      );
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()).setIssuesMode(true));
-    Map<String, String> projectSettings = ref.settings(project.key());
-    assertThat(projectSettings).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR"
-      ));
-  }
-
-  @Test
-  public void return_project_with_module_settings() {
-    ComponentDto project = ComponentTesting.newProjectDto();
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    tester.get(DbClient.class).componentDao().insert(dbSession, module);
-
-    // Module properties
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()));
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId()));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
-    assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"
-      ));
-    assertThat(ref.settings(module.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR-SERVER",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"
-      ));
-  }
-
-  @Test
-  public void return_project_with_module_settings_inherited_from_project() {
-    ComponentDto project = ComponentTesting.newProjectDto();
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    tester.get(DbClient.class).componentDao().insert(dbSession, module);
-
-    // No property on module -> should have the same as project
-
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
-    assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"
-      ));
-    assertThat(ref.settings(module.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"
-      ));
-  }
-
-  @Test
-  public void return_project_with_module_with_sub_module() {
-    ComponentDto project = ComponentTesting.newProjectDto();
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    tester.get(DbClient.class).componentDao().insert(dbSession, module);
-
-    // Module properties
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()));
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId()));
-
-    ComponentDto subModule = ComponentTesting.newModuleDto(module);
-    tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
-
-    // Sub module properties
-    tester.get(DbClient.class).propertiesDao().insertProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER-DAO").setResourceId(subModule.getId()));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
-    assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"
-      ));
-    assertThat(ref.settings(module.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR-SERVER",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"
-      ));
-    assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR-SERVER-DAO",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"
-      ));
-  }
-
-  @Test
-  public void return_project_with_two_modules() {
-    ComponentDto project = ComponentTesting.newProjectDto();
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-
-    ComponentDto module1 = ComponentTesting.newModuleDto(project);
-    tester.get(DbClient.class).componentDao().insert(dbSession, module1);
-
-    // Module 1 properties
-    tester.get(DbClient.class).propertiesDao()
-      .insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module1.getId()));
-    // This property should not be found on the other module
-    tester.get(DbClient.class).propertiesDao()
-      .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module1.getId()));
-
-    ComponentDto module2 = ComponentTesting.newModuleDto(project);
-    tester.get(DbClient.class).componentDao().insert(dbSession, module2);
-
-    // Module 2 property
-    tester.get(DbClient.class).propertiesDao()
-      .insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-APPLICATION").setResourceId(module2.getId()));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
-    assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"
-      ));
-    assertThat(ref.settings(module1.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR-SERVER",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"
-      ));
-    assertThat(ref.settings(module2.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR-APPLICATION",
-      "sonar.jira.login.secured", "john"
-      ));
-  }
-
-  @Test
-  public void return_provisioned_project_settings() {
-    // No snapshot attached on the project -> provisioned project
-    ComponentDto project = ComponentTesting.newProjectDto();
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
-    assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"
-      ));
-  }
-
-  @Test
-  public void return_sub_module_settings() {
-
-    ComponentDto project = ComponentTesting.newProjectDto();
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-    // No project properties
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    tester.get(DbClient.class).componentDao().insert(dbSession, module);
-    // No module properties
-
-    ComponentDto subModule = ComponentTesting.newModuleDto(module);
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
-
-    // Sub module properties
-    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(subModule.getId()));
-    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(subModule.getId()));
-    tester.get(DbClient.class).propertiesDao()
-      .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId()));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(subModule.key()));
-    assertThat(ref.settings(project.key())).isEmpty();
-    assertThat(ref.settings(module.key())).isEmpty();
-    assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"
-      ));
-  }
-
-  @Test
-  public void return_sub_module_settings_including_settings_from_parent_modules() {
-    ComponentDto project = ComponentTesting.newProjectDto();
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project property
-    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    tester.get(DbClient.class).componentDao().insert(dbSession, module);
-
-    // Module property
-    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(module.getId()));
-
-    ComponentDto subModule = ComponentTesting.newModuleDto(module);
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
-
-    // Sub module properties
-    tester.get(DbClient.class).propertiesDao()
-      .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId()));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(subModule.key()));
-    assertThat(ref.settings(project.key())).isEmpty();
-    assertThat(ref.settings(module.key())).isEmpty();
-    assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"
-      ));
-  }
-
-  @Test
-  public void return_sub_module_settings_only_inherited_from_project() {
-    ComponentDto project = ComponentTesting.newProjectDto();
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-    tester.get(DbClient.class).propertiesDao()
-      .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId()));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    tester.get(DbClient.class).componentDao().insert(dbSession, module);
-    // No module property
-
-    ComponentDto subModule = ComponentTesting.newModuleDto(module);
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
-    // No sub module property
-
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(subModule.key()));
-    assertThat(ref.settings(project.key())).isEmpty();
-    assertThat(ref.settings(module.key())).isEmpty();
-    assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"
-      ));
-  }
-
-  @Test
-  public void return_sub_module_settings_inherited_from_project_and_module() {
-    ComponentDto project = ComponentTesting.newProjectDto();
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-    tester.get(DbClient.class).propertiesDao()
-      .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId()));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    tester.get(DbClient.class).componentDao().insert(dbSession, module);
-
-    // Module property
-    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()));
-
-    ComponentDto subModule = ComponentTesting.newModuleDto(module);
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
-    // No sub module property
-
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(subModule.key()));
-    assertThat(ref.settings(project.key())).isEmpty();
-    assertThat(ref.settings(module.key())).isEmpty();
-    assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR-SERVER",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"
-      ));
-  }
-
-  @Test
-  public void fail_if_no_permission() {
-    userSessionRule.login("john").setGlobalPermissions();
-
-    ComponentDto project = ComponentTesting.newProjectDto();
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    dbSession.commit();
-
-    try {
-      loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(ForbiddenException.class).hasMessage("You're not authorized to execute any SonarQube analysis. Please contact your SonarQube administrator.");
-    }
-  }
-
-  @Test
-  public void fail_when_not_preview_and_only_dry_run_permission() {
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
-
-    ComponentDto project = ComponentTesting.newProjectDto();
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    dbSession.commit();
-
-    try {
-      loader.load(ProjectDataQuery.create().setModuleKey(project.key()).setIssuesMode(false));
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(ForbiddenException.class).hasMessage(
-        "You're only authorized to execute a local (preview) SonarQube analysis without pushing the results to the SonarQube server. " +
-          "Please contact your SonarQube administrator.");
-    }
-  }
-
-  @Test
-  public void return_file_data_from_single_project() {
-    ComponentDto project = ComponentTesting.newProjectDto();
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    ComponentDto file = ComponentTesting.newFileDto(project, "file");
-    tester.get(DbClient.class).componentDao().insert(dbSession, file);
-    tester.get(FileSourceDao.class).insert(newFileSourceDto(file).setSrcHash("123456"));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
-    assertThat(ref.fileDataByPath(project.key())).hasSize(1);
-    FileData fileData = ref.fileData(project.key(), file.path());
-    assertThat(fileData.hash()).isEqualTo("123456");
-  }
-
-  @Test
-  public void return_file_data_from_multi_modules() {
-    ComponentDto project = ComponentTesting.newProjectDto();
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // File on project
-    ComponentDto projectFile = ComponentTesting.newFileDto(project, "projectFile");
-    tester.get(DbClient.class).componentDao().insert(dbSession, projectFile);
-    tester.get(FileSourceDao.class).insert(newFileSourceDto(projectFile).setSrcHash("123456"));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    tester.get(DbClient.class).componentDao().insert(dbSession, module);
-
-    // File on module
-    ComponentDto moduleFile = ComponentTesting.newFileDto(module, "moduleFile");
-    tester.get(DbClient.class).componentDao().insert(dbSession, moduleFile);
-    tester.get(FileSourceDao.class).insert(newFileSourceDto(moduleFile).setSrcHash("789456"));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
-    assertThat(ref.fileData(project.key(), projectFile.path()).hash()).isEqualTo("123456");
-    assertThat(ref.fileData(module.key(), moduleFile.path()).hash()).isEqualTo("789456");
-  }
-
-  @Test
-  public void return_file_data_from_module() {
-    ComponentDto project = ComponentTesting.newProjectDto();
-    tester.get(DbClient.class).componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // File on project
-    ComponentDto projectFile = ComponentTesting.newFileDto(project, "projectFile");
-    tester.get(DbClient.class).componentDao().insert(dbSession, projectFile);
-    tester.get(FileSourceDao.class).insert(newFileSourceDto(projectFile).setSrcHash("123456").setRevision("987654321"));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    tester.get(DbClient.class).componentDao().insert(dbSession, module);
-
-    // File on module
-    ComponentDto moduleFile = ComponentTesting.newFileDto(module, "moduleFile");
-    tester.get(DbClient.class).componentDao().insert(dbSession, moduleFile);
-    tester.get(FileSourceDao.class).insert(newFileSourceDto(moduleFile).setSrcHash("789456").setRevision("123456789"));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(module.key()));
-    assertThat(ref.fileData(module.key(), moduleFile.path()).hash()).isEqualTo("789456");
-    assertThat(ref.fileData(module.key(), moduleFile.path()).revision()).isEqualTo("123456789");
-    assertThat(ref.fileData(project.key(), projectFile.path())).isNull();
-  }
-
-  private void addDefaultProfile() {
-    QualityProfileDto profileDto = newQProfileDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
-      formatDateTime(new Date())).setDefault(true);
-    tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
-  }
-
-  private static FileSourceDto newFileSourceDto(ComponentDto file) {
-    return new FileSourceDto()
-      .setFileUuid(file.uuid())
-      .setProjectUuid(file.projectUuid())
-      // .setSourceData(",,,,,,,,,,,,,,,unchanged&#13;&#10;,,,,,,,,,,,,,,,content&#13;&#10;")
-      .setDataHash("0263047cd758c68c27683625f072f010")
-      .setLineHashes("8d7b3d6b83c0a517eac07e1aac94b773")
-      .setCreatedAt(System.currentTimeMillis())
-      .setUpdatedAt(System.currentTimeMillis())
-      .setDataType(Type.SOURCE)
-      .setRevision("123456789")
-      .setSrcHash("123456");
-  }
-
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/UsersActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/UsersActionTest.java
deleted file mode 100644 (file)
index 43c000c..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.server.batch;
-
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.config.Settings;
-import org.sonar.api.platform.Server;
-import org.sonar.batch.protocol.input.BatchInput.User;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.user.index.UserDoc;
-import org.sonar.server.user.index.UserIndex;
-import org.sonar.server.user.index.UserIndexDefinition;
-import org.sonar.server.ws.WsTester;
-
-import java.io.ByteArrayInputStream;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-public class UsersActionTest {
-
-  @ClassRule
-  public static EsTester es = new EsTester().addDefinitions(new UserIndexDefinition(new Settings()));
-  @Rule
-  public UserSessionRule userSessionRule = UserSessionRule.standalone();
-
-  UserIndex userIndex;
-
-  WsTester tester;
-
-  UsersAction usersAction;
-
-  @Before
-  public void before() {
-    es.truncateIndices();
-
-    userIndex = new UserIndex(es.client());
-    usersAction = new UsersAction(userIndex, userSessionRule);
-
-    tester = new WsTester(new BatchWs(new BatchIndex(mock(Server.class)), usersAction));
-  }
-
-  @Test
-  public void return_minimal_fields() throws Exception {
-    es.putDocuments(UserIndexDefinition.INDEX, UserIndexDefinition.TYPE_USER,
-      new UserDoc().setLogin("ada.lovelace").setName("Ada Lovelace").setActive(false),
-      new UserDoc().setLogin("grace.hopper").setName("Grace Hopper").setActive(true));
-
-    userSessionRule.login("sonarqtech").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
-
-    WsTester.TestRequest request = tester.newGetRequest("batch", "users").setParam("logins", "ada.lovelace,grace.hopper");
-
-    ByteArrayInputStream input = new ByteArrayInputStream(request.execute().output());
-
-    User user = User.parseDelimitedFrom(input);
-    assertThat(user.getLogin()).isEqualTo("ada.lovelace");
-    assertThat(user.getName()).isEqualTo("Ada Lovelace");
-
-    user = User.parseDelimitedFrom(input);
-    assertThat(user.getLogin()).isEqualTo("grace.hopper");
-    assertThat(user.getName()).isEqualTo("Grace Hopper");
-
-    assertThat(User.parseDelimitedFrom(input)).isNull();
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/scanner/GlobalActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/scanner/GlobalActionTest.java
new file mode 100644 (file)
index 0000000..69e19df
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * 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.server.scanner;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.metric.MetricDao;
+import org.sonar.db.metric.MetricDto;
+import org.sonar.db.property.PropertiesDao;
+import org.sonar.db.property.PropertyDto;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.WsTester;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class GlobalActionTest {
+  @Rule
+  public UserSessionRule userSessionRule = UserSessionRule.standalone();
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Mock
+  DbSession session;
+
+  @Mock
+  MetricDao metricDao;
+
+  @Mock
+  PropertiesDao propertiesDao;
+
+  WsTester tester;
+
+  @Before
+  public void setUp() {
+    DbClient dbClient = mock(DbClient.class);
+    when(dbClient.openSession(false)).thenReturn(session);
+    when(dbClient.metricDao()).thenReturn(metricDao);
+
+    tester = new WsTester(new ScannerWs(mock(ScannerIndex.class), new GlobalAction(dbClient, propertiesDao, userSessionRule)));
+  }
+
+  @Test
+  public void return_metrics() throws Exception {
+    userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.PREVIEW_EXECUTION);
+
+    when(metricDao.selectEnabled(session)).thenReturn(newArrayList(
+      new MetricDto().setId(1).setKey("coverage").setDescription("Coverage by unit tests").setValueType("PERCENT").setQualitative(true)
+        .setWorstValue(0d).setBestValue(100d).setOptimizedBestValue(false).setDirection(1).setEnabled(true)
+      ));
+
+    WsTester.TestRequest request = tester.newGetRequest("scanner", "global");
+    request.execute().assertJson(getClass(), "return_global_referentials.json");
+  }
+
+  @Test
+  public void return_global_settings() throws Exception {
+    userSessionRule.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.PREVIEW_EXECUTION);
+
+    when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList(
+      new PropertyDto().setKey("foo").setValue("bar"),
+      new PropertyDto().setKey("foo.secured").setValue("1234"),
+      new PropertyDto().setKey("foo.license.secured").setValue("5678")
+      ));
+
+    WsTester.TestRequest request = tester.newGetRequest("scanner", "global");
+    request.execute().assertJson(getClass(), "return_global_settings.json");
+  }
+
+  @Test
+  public void return_only_license_settings_without_scan_but_with_preview_permission() throws Exception {
+    userSessionRule.setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
+
+    when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList(
+      new PropertyDto().setKey("foo").setValue("bar"),
+      new PropertyDto().setKey("foo.secured").setValue("1234"),
+      new PropertyDto().setKey("foo.license.secured").setValue("5678")
+      ));
+
+    WsTester.TestRequest request = tester.newGetRequest("scanner", "global");
+    request.execute().assertJson(getClass(), "return_only_license_settings_without_scan_but_with_preview_permission.json");
+  }
+
+  @Test
+  public void access_forbidden_without_scan_and_preview_permission() throws Exception {
+    userSessionRule.setGlobalPermissions();
+
+    when(propertiesDao.selectGlobalProperties(session)).thenReturn(newArrayList(
+      new PropertyDto().setKey("foo").setValue("bar"),
+      new PropertyDto().setKey("foo.secured").setValue("1234"),
+      new PropertyDto().setKey("foo.license.secured").setValue("5678")
+      ));
+
+    thrown.expect(ForbiddenException.class);
+
+    tester.newGetRequest("scanner", "global").execute();
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/scanner/IssuesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/scanner/IssuesActionTest.java
new file mode 100644 (file)
index 0000000..ba9762e
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * 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.server.scanner;
+
+import java.io.ByteArrayInputStream;
+import java.util.Arrays;
+import javax.annotation.Nullable;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.sonar.api.config.Settings;
+import org.sonar.api.platform.Server;
+import org.sonar.api.security.DefaultGroups;
+import org.sonar.api.utils.System2;
+import org.sonar.batch.protocol.Constants.Severity;
+import org.sonar.batch.protocol.input.BatchInput.ServerIssue;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.db.component.ComponentTesting;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.issue.IssueTesting;
+import org.sonar.server.issue.index.IssueAuthorizationDao;
+import org.sonar.server.issue.index.IssueAuthorizationIndexer;
+import org.sonar.server.issue.index.IssueDoc;
+import org.sonar.server.issue.index.IssueIndex;
+import org.sonar.server.issue.index.IssueIndexDefinition;
+import org.sonar.server.issue.index.IssueIndexer;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.WsTester;
+import org.sonar.test.DbTests;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+@Category(DbTests.class)
+public class IssuesActionTest {
+
+  private final static String PROJECT_KEY = "struts";
+  private final static String MODULE_KEY = "struts-core";
+  private final static String FILE_KEY = "Action.java";
+
+  @Rule
+  public DbTester db = DbTester.create(System2.INSTANCE);
+
+  @ClassRule
+  public static EsTester es = new EsTester().addDefinitions(new IssueIndexDefinition(new Settings()));
+
+  @Rule
+  public UserSessionRule userSessionRule = UserSessionRule.standalone();
+
+  IssueIndex issueIndex;
+  IssueIndexer issueIndexer;
+  IssueAuthorizationIndexer issueAuthorizationIndexer;
+
+  WsTester tester;
+
+  IssuesAction issuesAction;
+
+  @Before
+  public void before() {
+    db.truncateTables();
+    es.truncateIndices();
+
+    issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSessionRule);
+    issueIndexer = new IssueIndexer(null, es.client());
+    issueAuthorizationIndexer = new IssueAuthorizationIndexer(null, es.client());
+    issuesAction = new IssuesAction(db.getDbClient(), issueIndex, userSessionRule, new ComponentFinder(db.getDbClient()));
+
+    tester = new WsTester(new ScannerWs(new ScannerIndex(mock(Server.class)), issuesAction));
+  }
+
+  @Test
+  public void return_minimal_fields() throws Exception {
+    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
+    ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey(MODULE_KEY);
+    ComponentDto file = ComponentTesting.newFileDto(module, "CDEF").setKey(FILE_KEY).setPath(null);
+    db.getDbClient().componentDao().insert(db.getSession(), project, module, file);
+    db.getSession().commit();
+
+    indexIssues(IssueTesting.newDoc("EFGH", file)
+      .setRuleKey("squid:AvoidCycle")
+      .setSeverity("BLOCKER")
+      .setStatus("RESOLVED")
+      .setResolution(null)
+      .setManualSeverity(false)
+      .setMessage(null)
+      .setLine(null)
+      .setChecksum(null)
+      .setAssignee(null));
+
+    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
+
+    WsTester.TestRequest request = tester.newGetRequest("scanner", "issues").setParam("key", PROJECT_KEY);
+
+    ServerIssue serverIssue = ServerIssue.parseDelimitedFrom(new ByteArrayInputStream(request.execute().output()));
+    assertThat(serverIssue.getKey()).isEqualTo("EFGH");
+    assertThat(serverIssue.getModuleKey()).isEqualTo(MODULE_KEY);
+    assertThat(serverIssue.hasPath()).isFalse();
+    assertThat(serverIssue.getRuleRepository()).isEqualTo("squid");
+    assertThat(serverIssue.getRuleKey()).isEqualTo("AvoidCycle");
+    assertThat(serverIssue.hasLine()).isFalse();
+    assertThat(serverIssue.hasMsg()).isFalse();
+    assertThat(serverIssue.hasResolution()).isFalse();
+    assertThat(serverIssue.getStatus()).isEqualTo("RESOLVED");
+    assertThat(serverIssue.getSeverity()).isEqualTo(Severity.BLOCKER);
+    assertThat(serverIssue.getManualSeverity()).isFalse();
+    assertThat(serverIssue.hasChecksum()).isFalse();
+    assertThat(serverIssue.hasAssigneeLogin()).isFalse();
+  }
+
+  @Test
+  public void issues_from_project() throws Exception {
+    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
+    ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey(MODULE_KEY);
+    ComponentDto file = ComponentTesting.newFileDto(module, "CDEF").setKey(FILE_KEY).setPath("src/org/struts/Action.java");
+    db.getDbClient().componentDao().insert(db.getSession(), project, module, file);
+    db.getSession().commit();
+
+    indexIssues(IssueTesting.newDoc("EFGH", file)
+      .setRuleKey("squid:AvoidCycle")
+      .setSeverity("BLOCKER")
+      .setStatus("RESOLVED")
+      .setResolution("FALSE-POSITIVE")
+      .setManualSeverity(false)
+      .setMessage("Do not use this method")
+      .setLine(200)
+      .setChecksum("123456")
+      .setAssignee("john"));
+
+    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
+
+    WsTester.TestRequest request = tester.newGetRequest("scanner", "issues").setParam("key", PROJECT_KEY);
+
+    ServerIssue serverIssue = ServerIssue.parseDelimitedFrom(new ByteArrayInputStream(request.execute().output()));
+    assertThat(serverIssue.getKey()).isEqualTo("EFGH");
+    assertThat(serverIssue.getModuleKey()).isEqualTo(MODULE_KEY);
+    assertThat(serverIssue.getPath()).isEqualTo("src/org/struts/Action.java");
+    assertThat(serverIssue.getRuleRepository()).isEqualTo("squid");
+    assertThat(serverIssue.getRuleKey()).isEqualTo("AvoidCycle");
+    assertThat(serverIssue.getLine()).isEqualTo(200);
+    assertThat(serverIssue.getMsg()).isEqualTo("Do not use this method");
+    assertThat(serverIssue.getResolution()).isEqualTo("FALSE-POSITIVE");
+    assertThat(serverIssue.getStatus()).isEqualTo("RESOLVED");
+    assertThat(serverIssue.getSeverity()).isEqualTo(Severity.BLOCKER);
+    assertThat(serverIssue.getManualSeverity()).isFalse();
+    assertThat(serverIssue.getChecksum()).isEqualTo("123456");
+    assertThat(serverIssue.getAssigneeLogin()).isEqualTo("john");
+  }
+
+  @Test
+  public void issues_from_module() throws Exception {
+    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
+    ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey(MODULE_KEY);
+    ComponentDto file = ComponentTesting.newFileDto(module, "CDEF").setKey(FILE_KEY).setPath("src/org/struts/Action.java");
+    db.getDbClient().componentDao().insert(db.getSession(), project, module, file);
+    db.getSession().commit();
+
+    indexIssues(IssueTesting.newDoc("EFGH", file)
+      .setRuleKey("squid:AvoidCycle")
+      .setSeverity("BLOCKER")
+      .setStatus("RESOLVED")
+      .setResolution("FALSE-POSITIVE")
+      .setManualSeverity(false)
+      .setMessage("Do not use this method")
+      .setLine(200)
+      .setChecksum("123456")
+      .setAssignee("john"));
+
+    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
+
+    WsTester.TestRequest request = tester.newGetRequest("scanner", "issues").setParam("key", MODULE_KEY);
+    ServerIssue serverIssue = ServerIssue.parseDelimitedFrom(new ByteArrayInputStream(request.execute().output()));
+    assertThat(serverIssue.getKey()).isEqualTo("EFGH");
+    assertThat(serverIssue.getModuleKey()).isEqualTo(MODULE_KEY);
+    assertThat(serverIssue.getPath()).isEqualTo("src/org/struts/Action.java");
+    assertThat(serverIssue.getRuleRepository()).isEqualTo("squid");
+    assertThat(serverIssue.getRuleKey()).isEqualTo("AvoidCycle");
+    assertThat(serverIssue.getLine()).isEqualTo(200);
+    assertThat(serverIssue.getMsg()).isEqualTo("Do not use this method");
+    assertThat(serverIssue.getResolution()).isEqualTo("FALSE-POSITIVE");
+    assertThat(serverIssue.getStatus()).isEqualTo("RESOLVED");
+    assertThat(serverIssue.getSeverity()).isEqualTo(Severity.BLOCKER);
+    assertThat(serverIssue.getManualSeverity()).isFalse();
+    assertThat(serverIssue.getChecksum()).isEqualTo("123456");
+    assertThat(serverIssue.getAssigneeLogin()).isEqualTo("john");
+  }
+
+  @Test
+  public void issues_from_file() throws Exception {
+    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
+    ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey(MODULE_KEY);
+    ComponentDto file = ComponentTesting.newFileDto(module, "CDEF").setKey(FILE_KEY).setPath("src/org/struts/Action.java");
+    db.getDbClient().componentDao().insert(db.getSession(), project, module, file);
+    db.getSession().commit();
+
+    indexIssues(IssueTesting.newDoc("EFGH", file)
+      .setRuleKey("squid:AvoidCycle")
+      .setSeverity("BLOCKER")
+      .setStatus("RESOLVED")
+      .setResolution("FALSE-POSITIVE")
+      .setManualSeverity(false)
+      .setMessage("Do not use this method")
+      .setLine(200)
+      .setChecksum("123456")
+      .setAssignee("john"));
+
+    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
+
+    WsTester.TestRequest request = tester.newGetRequest("scanner", "issues").setParam("key", FILE_KEY);
+    ServerIssue serverIssue = ServerIssue.parseDelimitedFrom(new ByteArrayInputStream(request.execute().output()));
+    assertThat(serverIssue.getKey()).isEqualTo("EFGH");
+    assertThat(serverIssue.getModuleKey()).isEqualTo(MODULE_KEY);
+    assertThat(serverIssue.getPath()).isEqualTo("src/org/struts/Action.java");
+    assertThat(serverIssue.getRuleRepository()).isEqualTo("squid");
+    assertThat(serverIssue.getRuleKey()).isEqualTo("AvoidCycle");
+    assertThat(serverIssue.getLine()).isEqualTo(200);
+    assertThat(serverIssue.getMsg()).isEqualTo("Do not use this method");
+    assertThat(serverIssue.getResolution()).isEqualTo("FALSE-POSITIVE");
+    assertThat(serverIssue.getStatus()).isEqualTo("RESOLVED");
+    assertThat(serverIssue.getSeverity()).isEqualTo(Severity.BLOCKER);
+    assertThat(serverIssue.getManualSeverity()).isFalse();
+    assertThat(serverIssue.getChecksum()).isEqualTo("123456");
+    assertThat(serverIssue.getAssigneeLogin()).isEqualTo("john");
+  }
+
+  @Test
+  public void issues_attached_on_module() throws Exception {
+    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
+    ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey(MODULE_KEY);
+    db.getDbClient().componentDao().insert(db.getSession(), project, module);
+    db.getSession().commit();
+
+    indexIssues(IssueTesting.newDoc("EFGH", module)
+      .setRuleKey("squid:AvoidCycle")
+      .setSeverity("BLOCKER")
+      .setStatus("RESOLVED")
+      .setResolution("FALSE-POSITIVE")
+      .setManualSeverity(false)
+      .setMessage("Do not use this method")
+      .setLine(200)
+      .setChecksum("123456")
+      .setAssignee("john"));
+
+    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
+
+    WsTester.TestRequest request = tester.newGetRequest("scanner", "issues").setParam("key", MODULE_KEY);
+    ServerIssue previousIssue = ServerIssue.parseDelimitedFrom(new ByteArrayInputStream(request.execute().output()));
+    assertThat(previousIssue.getKey()).isEqualTo("EFGH");
+    assertThat(previousIssue.getModuleKey()).isEqualTo(MODULE_KEY);
+    assertThat(previousIssue.hasPath()).isFalse();
+    assertThat(previousIssue.getRuleRepository()).isEqualTo("squid");
+    assertThat(previousIssue.getRuleKey()).isEqualTo("AvoidCycle");
+    assertThat(previousIssue.getLine()).isEqualTo(200);
+    assertThat(previousIssue.getMsg()).isEqualTo("Do not use this method");
+    assertThat(previousIssue.getResolution()).isEqualTo("FALSE-POSITIVE");
+    assertThat(previousIssue.getStatus()).isEqualTo("RESOLVED");
+    assertThat(previousIssue.getSeverity()).isEqualTo(Severity.BLOCKER);
+    assertThat(previousIssue.getManualSeverity()).isFalse();
+    assertThat(previousIssue.getChecksum()).isEqualTo("123456");
+    assertThat(previousIssue.getAssigneeLogin()).isEqualTo("john");
+  }
+
+  @Test
+  public void project_issues_attached_file_on_removed_module() throws Exception {
+    ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY);
+    // File and module are removed
+    ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey(MODULE_KEY).setEnabled(false);
+    ComponentDto file = ComponentTesting.newFileDto(module, "CDEF").setKey(FILE_KEY).setPath("src/org/struts/Action.java").setEnabled(false);
+    db.getDbClient().componentDao().insert(db.getSession(), project, module, file);
+    db.getSession().commit();
+
+    indexIssues(IssueTesting.newDoc("EFGH", file)
+      .setRuleKey("squid:AvoidCycle")
+      .setSeverity("BLOCKER")
+      .setStatus("RESOLVED")
+      .setResolution("FALSE-POSITIVE")
+      .setManualSeverity(false)
+      .setMessage("Do not use this method")
+      .setLine(200)
+      .setChecksum("123456")
+      .setAssignee("john"));
+
+    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
+
+    WsTester.TestRequest request = tester.newGetRequest("scanner", "issues").setParam("key", PROJECT_KEY);
+    ServerIssue serverIssue = ServerIssue.parseDelimitedFrom(new ByteArrayInputStream(request.execute().output()));
+    assertThat(serverIssue.getKey()).isEqualTo("EFGH");
+    // Module key of removed file should be returned
+    assertThat(serverIssue.getModuleKey()).isEqualTo(MODULE_KEY);
+  }
+
+  @Test(expected = ForbiddenException.class)
+  public void fail_without_preview_permission() throws Exception {
+    userSessionRule.login("henry").setGlobalPermissions(GlobalPermissions.PROVISIONING);
+
+    WsTester.TestRequest request = tester.newGetRequest("scanner", "issues").setParam("key", PROJECT_KEY);
+    request.execute();
+  }
+
+  private void indexIssues(IssueDoc... issues) {
+    issueIndexer.index(Arrays.asList(issues).iterator());
+    for (IssueDoc issue : issues) {
+      addIssueAuthorization(issue.projectUuid(), DefaultGroups.ANYONE, null);
+    }
+  }
+
+  private void addIssueAuthorization(String projectUuid, @Nullable String group, @Nullable String user) {
+    issueAuthorizationIndexer.index(newArrayList(new IssueAuthorizationDao.Dto(projectUuid, 1).addGroup(group).addUser(user)));
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/scanner/ProjectActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/scanner/ProjectActionTest.java
new file mode 100644 (file)
index 0000000..29ac51b
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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.server.scanner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.sonar.batch.protocol.input.ProjectRepositories;
+import org.sonar.server.ws.WsTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ProjectActionTest {
+
+  ProjectDataLoader projectDataLoader = mock(ProjectDataLoader.class);
+
+  WsTester tester;
+
+  @Before
+  public void setUp() {
+    tester = new WsTester(new ScannerWs(mock(ScannerIndex.class), new ProjectAction(projectDataLoader)));
+  }
+
+  @Test
+  public void project_referentials() throws Exception {
+    String projectKey = "org.codehaus.sonar:sonar";
+
+    ProjectRepositories projectReferentials = mock(ProjectRepositories.class);
+    when(projectReferentials.toJson()).thenReturn("{\"settingsByModule\": {}}");
+
+    ArgumentCaptor<ProjectDataQuery> queryArgumentCaptor = ArgumentCaptor.forClass(ProjectDataQuery.class);
+    when(projectDataLoader.load(queryArgumentCaptor.capture())).thenReturn(projectReferentials);
+
+    WsTester.TestRequest request = tester.newGetRequest("scanner", "project")
+      .setParam("key", projectKey)
+      .setParam("profile", "Default")
+      .setParam("preview", "false");
+    request.execute().assertJson("{\"settingsByModule\": {}}");
+
+    assertThat(queryArgumentCaptor.getValue().getModuleKey()).isEqualTo(projectKey);
+    assertThat(queryArgumentCaptor.getValue().getProfileName()).isEqualTo("Default");
+    assertThat(queryArgumentCaptor.getValue().isIssuesMode()).isFalse();
+  }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/scanner/ProjectDataLoaderMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/scanner/ProjectDataLoaderMediumTest.java
new file mode 100644 (file)
index 0000000..c4cf868
--- /dev/null
@@ -0,0 +1,571 @@
+/*
+ * 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.server.scanner;
+
+import com.google.common.collect.ImmutableMap;
+import java.util.Date;
+import java.util.Map;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.web.UserRole;
+import org.sonar.batch.protocol.input.FileData;
+import org.sonar.batch.protocol.input.ProjectRepositories;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.DbSession;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.property.PropertyDto;
+import org.sonar.db.qualityprofile.QualityProfileDto;
+import org.sonar.db.source.FileSourceDao;
+import org.sonar.db.source.FileSourceDto;
+import org.sonar.db.source.FileSourceDto.Type;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.qualityprofile.QProfileName;
+import org.sonar.server.tester.ServerTester;
+import org.sonar.server.tester.UserSessionRule;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+import static org.sonar.api.utils.DateUtils.formatDateTime;
+import static org.sonar.server.qualityprofile.QProfileTesting.newQProfileDto;
+
+public class ProjectDataLoaderMediumTest {
+
+  @ClassRule
+  public static ServerTester tester = new ServerTester().addXoo();
+
+  @Rule
+  public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);
+
+  DbSession dbSession;
+
+  ProjectDataLoader loader;
+
+  @Before
+  public void before() {
+    tester.clearDbAndIndexes();
+    dbSession = tester.get(DbClient.class).openSession(false);
+    loader = tester.get(ProjectDataLoader.class);
+  }
+
+  @After
+  public void after() {
+    dbSession.close();
+  }
+
+  @Test
+  public void return_project_settings() {
+    ComponentDto project = ComponentTesting.newProjectDto();
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())
+      );
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())
+      );
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
+    Map<String, String> projectSettings = ref.settings(project.key());
+    assertThat(projectSettings).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"
+      ));
+  }
+
+  @Test
+  public void not_returned_secured_settings_with_only_preview_permission() {
+    ComponentDto project = ComponentTesting.newProjectDto();
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION).addProjectUuidPermissions(UserRole.USER, project.uuid());
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())
+      );
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())
+      );
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()).setIssuesMode(true));
+    Map<String, String> projectSettings = ref.settings(project.key());
+    assertThat(projectSettings).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR"
+      ));
+  }
+
+  @Test
+  public void return_project_with_module_settings() {
+    ComponentDto project = ComponentTesting.newProjectDto();
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    tester.get(DbClient.class).componentDao().insert(dbSession, module);
+
+    // Module properties
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()));
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId()));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
+    assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"
+      ));
+    assertThat(ref.settings(module.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR-SERVER",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"
+      ));
+  }
+
+  @Test
+  public void return_project_with_module_settings_inherited_from_project() {
+    ComponentDto project = ComponentTesting.newProjectDto();
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    tester.get(DbClient.class).componentDao().insert(dbSession, module);
+
+    // No property on module -> should have the same as project
+
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
+    assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"
+      ));
+    assertThat(ref.settings(module.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"
+      ));
+  }
+
+  @Test
+  public void return_project_with_module_with_sub_module() {
+    ComponentDto project = ComponentTesting.newProjectDto();
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    tester.get(DbClient.class).componentDao().insert(dbSession, module);
+
+    // Module properties
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()));
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId()));
+
+    ComponentDto subModule = ComponentTesting.newModuleDto(module);
+    tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
+
+    // Sub module properties
+    tester.get(DbClient.class).propertiesDao().insertProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER-DAO").setResourceId(subModule.getId()));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
+    assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"
+      ));
+    assertThat(ref.settings(module.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR-SERVER",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"
+      ));
+    assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR-SERVER-DAO",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"
+      ));
+  }
+
+  @Test
+  public void return_project_with_two_modules() {
+    ComponentDto project = ComponentTesting.newProjectDto();
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+
+    ComponentDto module1 = ComponentTesting.newModuleDto(project);
+    tester.get(DbClient.class).componentDao().insert(dbSession, module1);
+
+    // Module 1 properties
+    tester.get(DbClient.class).propertiesDao()
+      .insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module1.getId()));
+    // This property should not be found on the other module
+    tester.get(DbClient.class).propertiesDao()
+      .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module1.getId()));
+
+    ComponentDto module2 = ComponentTesting.newModuleDto(project);
+    tester.get(DbClient.class).componentDao().insert(dbSession, module2);
+
+    // Module 2 property
+    tester.get(DbClient.class).propertiesDao()
+      .insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-APPLICATION").setResourceId(module2.getId()));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
+    assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"
+      ));
+    assertThat(ref.settings(module1.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR-SERVER",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"
+      ));
+    assertThat(ref.settings(module2.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR-APPLICATION",
+      "sonar.jira.login.secured", "john"
+      ));
+  }
+
+  @Test
+  public void return_provisioned_project_settings() {
+    // No snapshot attached on the project -> provisioned project
+    ComponentDto project = ComponentTesting.newProjectDto();
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
+    assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"
+      ));
+  }
+
+  @Test
+  public void return_sub_module_settings() {
+
+    ComponentDto project = ComponentTesting.newProjectDto();
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+    // No project properties
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    tester.get(DbClient.class).componentDao().insert(dbSession, module);
+    // No module properties
+
+    ComponentDto subModule = ComponentTesting.newModuleDto(module);
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
+
+    // Sub module properties
+    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(subModule.getId()));
+    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(subModule.getId()));
+    tester.get(DbClient.class).propertiesDao()
+      .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId()));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(subModule.key()));
+    assertThat(ref.settings(project.key())).isEmpty();
+    assertThat(ref.settings(module.key())).isEmpty();
+    assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"
+      ));
+  }
+
+  @Test
+  public void return_sub_module_settings_including_settings_from_parent_modules() {
+    ComponentDto project = ComponentTesting.newProjectDto();
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project property
+    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    tester.get(DbClient.class).componentDao().insert(dbSession, module);
+
+    // Module property
+    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(module.getId()));
+
+    ComponentDto subModule = ComponentTesting.newModuleDto(module);
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
+
+    // Sub module properties
+    tester.get(DbClient.class).propertiesDao()
+      .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId()));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(subModule.key()));
+    assertThat(ref.settings(project.key())).isEmpty();
+    assertThat(ref.settings(module.key())).isEmpty();
+    assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"
+      ));
+  }
+
+  @Test
+  public void return_sub_module_settings_only_inherited_from_project() {
+    ComponentDto project = ComponentTesting.newProjectDto();
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+    tester.get(DbClient.class).propertiesDao()
+      .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId()));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    tester.get(DbClient.class).componentDao().insert(dbSession, module);
+    // No module property
+
+    ComponentDto subModule = ComponentTesting.newModuleDto(module);
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
+    // No sub module property
+
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(subModule.key()));
+    assertThat(ref.settings(project.key())).isEmpty();
+    assertThat(ref.settings(module.key())).isEmpty();
+    assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"
+      ));
+  }
+
+  @Test
+  public void return_sub_module_settings_inherited_from_project_and_module() {
+    ComponentDto project = ComponentTesting.newProjectDto();
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+    tester.get(DbClient.class).propertiesDao()
+      .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId()));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    tester.get(DbClient.class).componentDao().insert(dbSession, module);
+
+    // Module property
+    tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()));
+
+    ComponentDto subModule = ComponentTesting.newModuleDto(module);
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    tester.get(DbClient.class).componentDao().insert(dbSession, subModule);
+    // No sub module property
+
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(subModule.key()));
+    assertThat(ref.settings(project.key())).isEmpty();
+    assertThat(ref.settings(module.key())).isEmpty();
+    assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR-SERVER",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"
+      ));
+  }
+
+  @Test
+  public void fail_if_no_permission() {
+    userSessionRule.login("john").setGlobalPermissions();
+
+    ComponentDto project = ComponentTesting.newProjectDto();
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    dbSession.commit();
+
+    try {
+      loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
+      fail();
+    } catch (Exception e) {
+      assertThat(e).isInstanceOf(ForbiddenException.class).hasMessage("You're not authorized to execute any SonarQube analysis. Please contact your SonarQube administrator.");
+    }
+  }
+
+  @Test
+  public void fail_when_not_preview_and_only_dry_run_permission() {
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
+
+    ComponentDto project = ComponentTesting.newProjectDto();
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    dbSession.commit();
+
+    try {
+      loader.load(ProjectDataQuery.create().setModuleKey(project.key()).setIssuesMode(false));
+      fail();
+    } catch (Exception e) {
+      assertThat(e).isInstanceOf(ForbiddenException.class).hasMessage(
+        "You're only authorized to execute a local (preview) SonarQube analysis without pushing the results to the SonarQube server. " +
+          "Please contact your SonarQube administrator.");
+    }
+  }
+
+  @Test
+  public void return_file_data_from_single_project() {
+    ComponentDto project = ComponentTesting.newProjectDto();
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    ComponentDto file = ComponentTesting.newFileDto(project, "file");
+    tester.get(DbClient.class).componentDao().insert(dbSession, file);
+    tester.get(FileSourceDao.class).insert(newFileSourceDto(file).setSrcHash("123456"));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
+    assertThat(ref.fileDataByPath(project.key())).hasSize(1);
+    FileData fileData = ref.fileData(project.key(), file.path());
+    assertThat(fileData.hash()).isEqualTo("123456");
+  }
+
+  @Test
+  public void return_file_data_from_multi_modules() {
+    ComponentDto project = ComponentTesting.newProjectDto();
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // File on project
+    ComponentDto projectFile = ComponentTesting.newFileDto(project, "projectFile");
+    tester.get(DbClient.class).componentDao().insert(dbSession, projectFile);
+    tester.get(FileSourceDao.class).insert(newFileSourceDto(projectFile).setSrcHash("123456"));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    tester.get(DbClient.class).componentDao().insert(dbSession, module);
+
+    // File on module
+    ComponentDto moduleFile = ComponentTesting.newFileDto(module, "moduleFile");
+    tester.get(DbClient.class).componentDao().insert(dbSession, moduleFile);
+    tester.get(FileSourceDao.class).insert(newFileSourceDto(moduleFile).setSrcHash("789456"));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(project.key()));
+    assertThat(ref.fileData(project.key(), projectFile.path()).hash()).isEqualTo("123456");
+    assertThat(ref.fileData(module.key(), moduleFile.path()).hash()).isEqualTo("789456");
+  }
+
+  @Test
+  public void return_file_data_from_module() {
+    ComponentDto project = ComponentTesting.newProjectDto();
+    tester.get(DbClient.class).componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // File on project
+    ComponentDto projectFile = ComponentTesting.newFileDto(project, "projectFile");
+    tester.get(DbClient.class).componentDao().insert(dbSession, projectFile);
+    tester.get(FileSourceDao.class).insert(newFileSourceDto(projectFile).setSrcHash("123456").setRevision("987654321"));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    tester.get(DbClient.class).componentDao().insert(dbSession, module);
+
+    // File on module
+    ComponentDto moduleFile = ComponentTesting.newFileDto(module, "moduleFile");
+    tester.get(DbClient.class).componentDao().insert(dbSession, moduleFile);
+    tester.get(FileSourceDao.class).insert(newFileSourceDto(moduleFile).setSrcHash("789456").setRevision("123456789"));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = loader.load(ProjectDataQuery.create().setModuleKey(module.key()));
+    assertThat(ref.fileData(module.key(), moduleFile.path()).hash()).isEqualTo("789456");
+    assertThat(ref.fileData(module.key(), moduleFile.path()).revision()).isEqualTo("123456789");
+    assertThat(ref.fileData(project.key(), projectFile.path())).isNull();
+  }
+
+  private void addDefaultProfile() {
+    QualityProfileDto profileDto = newQProfileDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
+      formatDateTime(new Date())).setDefault(true);
+    tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
+  }
+
+  private static FileSourceDto newFileSourceDto(ComponentDto file) {
+    return new FileSourceDto()
+      .setFileUuid(file.uuid())
+      .setProjectUuid(file.projectUuid())
+      // .setSourceData(",,,,,,,,,,,,,,,unchanged&#13;&#10;,,,,,,,,,,,,,,,content&#13;&#10;")
+      .setDataHash("0263047cd758c68c27683625f072f010")
+      .setLineHashes("8d7b3d6b83c0a517eac07e1aac94b773")
+      .setCreatedAt(System.currentTimeMillis())
+      .setUpdatedAt(System.currentTimeMillis())
+      .setDataType(Type.SOURCE)
+      .setRevision("123456789")
+      .setSrcHash("123456");
+  }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/scanner/ScannerIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/scanner/ScannerIndexTest.java
new file mode 100644 (file)
index 0000000..239a340
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 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.server.scanner;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.CharUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.platform.Server;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ScannerIndexTest {
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  File jar;
+
+  Server server = mock(Server.class);
+
+  @Before
+  public void prepare_fs() throws IOException {
+    File rootDir = temp.newFolder();
+    when(server.getRootDir()).thenReturn(rootDir);
+
+    File batchDir = new File(rootDir, "lib/batch");
+    FileUtils.forceMkdir(batchDir);
+    jar = new File(batchDir, "sonar-batch.jar");
+    FileUtils.writeStringToFile(new File(batchDir, "sonar-batch.jar"), "foo");
+  }
+
+  @Test
+  public void get_index() {
+    ScannerIndex scannerIndex = new ScannerIndex(server);
+    scannerIndex.start();
+
+    String index = scannerIndex.getIndex();
+    assertThat(index).isEqualTo("sonar-batch.jar|acbd18db4cc2f85cedef654fccc4a4d8" + CharUtils.LF);
+
+    scannerIndex.stop();
+  }
+
+  @Test
+  public void get_file() {
+    ScannerIndex scannerIndex = new ScannerIndex(server);
+    scannerIndex.start();
+
+    File file = scannerIndex.getFile("sonar-batch.jar");
+    assertThat(file).isEqualTo(jar);
+  }
+
+  /**
+   * Do not allow to download files located outside the directory lib/batch, for example
+   * /etc/passwd
+   */
+  @Test
+  public void check_location_of_file() {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Bad filename: ../sonar-batch.jar");
+
+    ScannerIndex scannerIndex = new ScannerIndex(server);
+    scannerIndex.start();
+
+    scannerIndex.getFile("../sonar-batch.jar");
+  }
+
+  @Test
+  public void file_does_not_exist() {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Bad filename: other.jar");
+
+    ScannerIndex scannerIndex = new ScannerIndex(server);
+    scannerIndex.start();
+
+    scannerIndex.getFile("other.jar");
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/scanner/ScannerWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/scanner/ScannerWsModuleTest.java
new file mode 100644 (file)
index 0000000..6b81f52
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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.server.scanner;
+
+import org.junit.Test;
+import org.sonar.core.platform.ComponentContainer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ScannerWsModuleTest {
+  @Test
+  public void verify_count_of_added_components() {
+    ComponentContainer container = new ComponentContainer();
+    new ScannerWsModule().configure(container);
+    assertThat(container.size()).isEqualTo(9);
+  }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/scanner/ScannerWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/scanner/ScannerWsTest.java
new file mode 100644 (file)
index 0000000..e672e13
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 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.server.scanner;
+
+import java.io.File;
+import org.apache.commons.io.FileUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.db.property.PropertiesDao;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.issue.index.IssueIndex;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.WsTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ScannerWsTest {
+  @Rule
+  public UserSessionRule userSessionRule = UserSessionRule.standalone();
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Mock
+  ScannerIndex scannerIndex;
+
+  WsTester tester;
+
+  @Before
+  public void before() {
+    tester = new WsTester(new ScannerWs(scannerIndex,
+      new GlobalAction(mock(DbClient.class), mock(PropertiesDao.class), userSessionRule),
+      new ProjectAction(mock(ProjectDataLoader.class)),
+      new IssuesAction(mock(DbClient.class), mock(IssueIndex.class), userSessionRule, mock(ComponentFinder.class))));
+  }
+
+  @Test
+  public void download_index() throws Exception {
+    when(scannerIndex.getIndex()).thenReturn("sonar-batch.jar|acbd18db4cc2f85cedef654fccc4a4d8");
+
+    String index = tester.newGetRequest("scanner", "index").execute().outputAsString();
+    assertThat(index).isEqualTo("sonar-batch.jar|acbd18db4cc2f85cedef654fccc4a4d8");
+  }
+
+  @Test
+  public void download_file() throws Exception {
+    String filename = "sonar-batch.jar";
+
+    File file = temp.newFile(filename);
+    FileUtils.writeStringToFile(file, "foo");
+    when(scannerIndex.getFile(filename)).thenReturn(file);
+
+    String jar = tester.newGetRequest("scanner", "file").setParam("name", filename).execute().outputAsString();
+    assertThat(jar).isEqualTo("foo");
+  }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/scanner/UsersActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/scanner/UsersActionTest.java
new file mode 100644 (file)
index 0000000..450a70d
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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.server.scanner;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.api.platform.Server;
+import org.sonar.batch.protocol.input.BatchInput.User;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.user.index.UserDoc;
+import org.sonar.server.user.index.UserIndex;
+import org.sonar.server.user.index.UserIndexDefinition;
+import org.sonar.server.ws.WsTester;
+
+import java.io.ByteArrayInputStream;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class UsersActionTest {
+
+  @ClassRule
+  public static EsTester es = new EsTester().addDefinitions(new UserIndexDefinition(new Settings()));
+  @Rule
+  public UserSessionRule userSessionRule = UserSessionRule.standalone();
+
+  UserIndex userIndex;
+
+  WsTester tester;
+
+  UsersAction usersAction;
+
+  @Before
+  public void before() {
+    es.truncateIndices();
+
+    userIndex = new UserIndex(es.client());
+    usersAction = new UsersAction(userIndex, userSessionRule);
+
+    tester = new WsTester(new ScannerWs(new ScannerIndex(mock(Server.class)), usersAction));
+  }
+
+  @Test
+  public void return_minimal_fields() throws Exception {
+    es.putDocuments(UserIndexDefinition.INDEX, UserIndexDefinition.TYPE_USER,
+      new UserDoc().setLogin("ada.lovelace").setName("Ada Lovelace").setActive(false),
+      new UserDoc().setLogin("grace.hopper").setName("Grace Hopper").setActive(true));
+
+    userSessionRule.login("sonarqtech").setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION);
+
+    WsTester.TestRequest request = tester.newGetRequest("scanner", "users").setParam("logins", "ada.lovelace,grace.hopper");
+
+    ByteArrayInputStream input = new ByteArrayInputStream(request.execute().output());
+
+    User user = User.parseDelimitedFrom(input);
+    assertThat(user.getLogin()).isEqualTo("ada.lovelace");
+    assertThat(user.getName()).isEqualTo("Ada Lovelace");
+
+    user = User.parseDelimitedFrom(input);
+    assertThat(user.getLogin()).isEqualTo("grace.hopper");
+    assertThat(user.getName()).isEqualTo("Grace Hopper");
+
+    assertThat(User.parseDelimitedFrom(input)).isNull();
+  }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_global_referentials.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_global_referentials.json
deleted file mode 100644 (file)
index 2e558ed..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "timestamp": 0,
-  "metrics": [
-    {
-      "id": 1,
-      "key": "coverage",
-      "valueType": "PERCENT",
-      "description": "Coverage by unit tests",
-      "direction": 1,
-      "name": "coverage",
-      "qualitative": true,
-      "userManaged": false,
-      "worstValue": 0.0,
-      "bestValue": 100.0,
-      "optimizedBestValue": false
-    }
-  ],
-  "globalSettings": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_global_settings.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_global_settings.json
deleted file mode 100644 (file)
index d6faa69..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "timestamp": 0,
-  "metrics": [],
-  "globalSettings": {
-    "foo" : "bar",
-    "foo.secured" : "1234",
-    "foo.license.secured" : "5678"
-  }
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_only_license_settings_without_scan_but_with_preview_permission.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/GlobalActionTest/return_only_license_settings_without_scan_but_with_preview_permission.json
deleted file mode 100644 (file)
index b0af2f8..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "timestamp": 0,
-  "metrics": [],
-  "globalSettings": {
-    "foo" : "bar",
-    "foo.license.secured" : "5678"
-  }
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectActionTest/project_referentials.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectActionTest/project_referentials.json
deleted file mode 100644 (file)
index ff04061..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "timestamp": 0,
-  "qprofilesByLanguage": {
-    "java": {
-      "key": "abcd",
-      "name": "Default",
-      "language": "java",
-      "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
-    }
-  },
-  "activeRules": [
-    {
-      "repositoryKey": "squid",
-      "ruleKey": "AvoidCycle",
-      "name": "Avoid Cycle",
-      "severity": "MINOR",
-      "internalKey": "squid-1",
-      "language": "java",
-      "params": {
-        "max" : "2"
-      }
-    }
-  ],
-  "settingsByModule": {
-    "org.codehaus.sonar:sonar": {
-      "sonar.jira.project.key": "SONAR",
-      "sonar.jira.login.secured": "john"
-    }
-  },
-  "fileDataByModuleAndPath": {}
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/scanner/GlobalActionTest/return_global_referentials.json b/server/sonar-server/src/test/resources/org/sonar/server/scanner/GlobalActionTest/return_global_referentials.json
new file mode 100644 (file)
index 0000000..2e558ed
--- /dev/null
@@ -0,0 +1,19 @@
+{
+  "timestamp": 0,
+  "metrics": [
+    {
+      "id": 1,
+      "key": "coverage",
+      "valueType": "PERCENT",
+      "description": "Coverage by unit tests",
+      "direction": 1,
+      "name": "coverage",
+      "qualitative": true,
+      "userManaged": false,
+      "worstValue": 0.0,
+      "bestValue": 100.0,
+      "optimizedBestValue": false
+    }
+  ],
+  "globalSettings": {}
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/scanner/GlobalActionTest/return_global_settings.json b/server/sonar-server/src/test/resources/org/sonar/server/scanner/GlobalActionTest/return_global_settings.json
new file mode 100644 (file)
index 0000000..d6faa69
--- /dev/null
@@ -0,0 +1,9 @@
+{
+  "timestamp": 0,
+  "metrics": [],
+  "globalSettings": {
+    "foo" : "bar",
+    "foo.secured" : "1234",
+    "foo.license.secured" : "5678"
+  }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/scanner/GlobalActionTest/return_only_license_settings_without_scan_but_with_preview_permission.json b/server/sonar-server/src/test/resources/org/sonar/server/scanner/GlobalActionTest/return_only_license_settings_without_scan_but_with_preview_permission.json
new file mode 100644 (file)
index 0000000..b0af2f8
--- /dev/null
@@ -0,0 +1,8 @@
+{
+  "timestamp": 0,
+  "metrics": [],
+  "globalSettings": {
+    "foo" : "bar",
+    "foo.license.secured" : "5678"
+  }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/scanner/ProjectActionTest/project_referentials.json b/server/sonar-server/src/test/resources/org/sonar/server/scanner/ProjectActionTest/project_referentials.json
new file mode 100644 (file)
index 0000000..ff04061
--- /dev/null
@@ -0,0 +1,31 @@
+{
+  "timestamp": 0,
+  "qprofilesByLanguage": {
+    "java": {
+      "key": "abcd",
+      "name": "Default",
+      "language": "java",
+      "rulesUpdatedAt": "2014-01-14T13:00:00+0100"
+    }
+  },
+  "activeRules": [
+    {
+      "repositoryKey": "squid",
+      "ruleKey": "AvoidCycle",
+      "name": "Avoid Cycle",
+      "severity": "MINOR",
+      "internalKey": "squid-1",
+      "language": "java",
+      "params": {
+        "max" : "2"
+      }
+    }
+  ],
+  "settingsByModule": {
+    "org.codehaus.sonar:sonar": {
+      "sonar.jira.project.key": "SONAR",
+      "sonar.jira.login.secured": "john"
+    }
+  },
+  "fileDataByModuleAndPath": {}
+}
index 098d8cccf9abaae80d405cd25af44f066f45bb72..1ccfc4e22161828cd2bb5678844a642b8b6df14f 100644 (file)
@@ -9,8 +9,8 @@ ActionController::Routing::Routes.draw do |map|
   map.connect 'api', :controller => 'api/java_ws', :action => 'redirect_to_ws_listing'
 
   # deprecated, sonar-runner should use batch/index and batch/file?name=xxx
-  map.connect 'batch_bootstrap/index', :controller => 'api/java_ws', :action => 'index', :wspath => 'batch', :wsaction => 'index'
-  map.connect 'batch/:name', :controller => 'api/java_ws', :action => 'index', :wspath => 'batch', :wsaction => 'file', :requirements => { :name => /.*/ }
+  map.connect 'batch_bootstrap/index', :controller => 'api/java_ws', :action => 'index', :wspath => 'scanner', :wsaction => 'index'
+  map.connect 'scanner/:name', :controller => 'api/java_ws', :action => 'index', :wspath => 'scanner', :wsaction => 'file', :requirements => { :name => /.*/ }
 
   map.connect 'api/server/:action', :controller => 'api/server'
   map.connect 'api/resoures', :controller => 'api/resources', :action => 'index'
index 51e7aaa4635ea4954c55b2a293e5de6be4d3d983..0575d6a2c720cc6a8c24276192c6063ad858fd88 100644 (file)
@@ -30,7 +30,7 @@ import org.sonar.batch.protocol.input.GlobalRepositories;
 
 public class DefaultGlobalRepositoriesLoader implements GlobalRepositoriesLoader {
 
-  private static final String BATCH_GLOBAL_URL = "/batch/global";
+  private static final String BATCH_GLOBAL_URL = "/scanner/global";
 
   private final WSLoader wsLoader;
 
index f47200656131515ce21c670f5acff0cafaeb2af5..add0f3d157eb5d492344171c1948c3cb9e7cd162 100644 (file)
@@ -33,7 +33,7 @@ import org.sonar.batch.util.BatchUtils;
 public class DefaultProjectRepositoriesLoader implements ProjectRepositoriesLoader {
 
   private static final Logger LOG = LoggerFactory.getLogger(DefaultProjectRepositoriesLoader.class);
-  private static final String BATCH_PROJECT_URL = "/batch/project";
+  private static final String BATCH_PROJECT_URL = "/scanner/project";
 
   private final WSLoader wsLoader;
   private final DefaultAnalysisMode analysisMode;
index 8cd966abb4defe7aba172bf6aa03e64a924be1e0..aefe0569275a7672ce77e674cc6857b41e86c11f 100644 (file)
@@ -40,7 +40,7 @@ public class DefaultServerIssuesLoader implements ServerIssuesLoader {
 
   @Override
   public boolean load(String componentKey, Function<ServerIssue, Void> consumer) {
-    WSLoaderResult<ByteSource> result = wsLoader.loadSource("/batch/issues?key=" + BatchUtils.encodeForUrl(componentKey));
+    WSLoaderResult<ByteSource> result = wsLoader.loadSource("/scanner/issues?key=" + BatchUtils.encodeForUrl(componentKey));
     parseIssues(result.get(), consumer);
     return result.isFromCache();
   }
index 09b5c027553c54f5657c6d16f09e72cc3ca3d1bc..d40f918f87b501550e2274ac071fbd6a70f3ed6b 100644 (file)
@@ -73,7 +73,7 @@ public class UserRepositoryLoader {
   }
 
   private ByteSource loadQuery(String loginsQuery, @Nullable MutableBoolean fromCache) {
-    WSLoaderResult<ByteSource> result = wsLoader.loadSource("/batch/users?logins=" + loginsQuery);
+    WSLoaderResult<ByteSource> result = wsLoader.loadSource("/scanner/users?logins=" + loginsQuery);
     if (fromCache != null) {
       fromCache.setValue(result.isFromCache());
     }
index 2621af3347677a42e464ddc90361121d87dffe76..a4dade54f2d8d3db1378c6b8f7947cbdf6858c21 100644 (file)
  */
 package org.sonar.batch.cache;
 
-import static org.mockito.Mockito.when;
-
-import org.sonar.batch.repository.ProjectRepositoriesFactory;
-
-import org.sonar.batch.repository.DefaultProjectRepositoriesFactory;
-import org.junit.Rule;
-import org.junit.rules.ExpectedException;
-import org.sonar.batch.repository.ProjectSettingsRepo;
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
-import org.sonar.batch.protocol.input.ActiveRule;
-import org.sonar.batch.protocol.input.QProfile;
-import org.apache.commons.lang.mutable.MutableBoolean;
-import org.sonar.batch.repository.DefaultProjectSettingsLoader;
-import org.sonar.batch.rule.DefaultActiveRulesLoader;
-import org.sonar.batch.repository.DefaultQualityProfileLoader;
-import org.sonar.batch.repository.ProjectSettingsLoader;
-import org.sonar.batch.rule.ActiveRulesLoader;
-import org.sonar.batch.repository.QualityProfileLoader;
-import org.sonar.batch.analysis.DefaultAnalysisMode;
-import org.sonar.batch.analysis.AnalysisProperties;
-import org.sonar.batch.protocol.input.ProjectRepositories;
-import org.sonar.batch.repository.DefaultServerIssuesLoader;
-import org.sonar.batch.repository.DefaultProjectRepositoriesLoader;
-import org.sonar.api.batch.bootstrap.ProjectReactor;
 import com.google.common.io.ByteSource;
-
+import com.google.common.io.Resources;
 import java.io.IOException;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.util.Date;
 import java.util.HashMap;
-
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import com.google.common.io.Resources;
-import org.junit.Test;
+import org.apache.commons.lang.mutable.MutableBoolean;
 import org.junit.Before;
-import org.mockito.MockitoAnnotations;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.bootstrap.ProjectReactor;
+import org.sonar.batch.analysis.AnalysisProperties;
+import org.sonar.batch.analysis.DefaultAnalysisMode;
+import org.sonar.batch.protocol.input.ActiveRule;
+import org.sonar.batch.protocol.input.ProjectRepositories;
+import org.sonar.batch.protocol.input.QProfile;
+import org.sonar.batch.repository.DefaultProjectRepositoriesFactory;
+import org.sonar.batch.repository.DefaultProjectRepositoriesLoader;
+import org.sonar.batch.repository.DefaultProjectSettingsLoader;
+import org.sonar.batch.repository.DefaultQualityProfileLoader;
+import org.sonar.batch.repository.DefaultServerIssuesLoader;
+import org.sonar.batch.repository.ProjectRepositoriesFactory;
 import org.sonar.batch.repository.ProjectRepositoriesLoader;
+import org.sonar.batch.repository.ProjectSettingsLoader;
+import org.sonar.batch.repository.ProjectSettingsRepo;
+import org.sonar.batch.repository.QualityProfileLoader;
 import org.sonar.batch.repository.ServerIssuesLoader;
 import org.sonar.batch.repository.user.UserRepositoryLoader;
+import org.sonar.batch.rule.ActiveRulesLoader;
+import org.sonar.batch.rule.DefaultActiveRulesLoader;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
 
 public class ProjectCacheSynchronizerTest {
-  private static final String BATCH_PROJECT = "/batch/project?key=org.codehaus.sonar-plugins%3Asonar-scm-git-plugin&preview=true";
-  private static final String ISSUES = "/batch/issues?key=org.codehaus.sonar-plugins%3Asonar-scm-git-plugin";
+  private static final String BATCH_PROJECT = "/scanner/project?key=org.codehaus.sonar-plugins%3Asonar-scm-git-plugin&preview=true";
+  private static final String ISSUES = "/scanner/issues?key=org.codehaus.sonar-plugins%3Asonar-scm-git-plugin";
   private static final String PROJECT_KEY = "org.codehaus.sonar-plugins:sonar-scm-git-plugin";
 
   @Rule
index ee9786e53a66dc33a44223fb252b5182651b106e..df13b2ae6a7c1e29ec6783a74c14ca3056604ae5 100644 (file)
  */
 package org.sonar.batch.repository;
 
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.sonar.batch.cache.WSLoaderResult;
-import org.sonar.batch.protocol.input.GlobalRepositories;
 import org.apache.commons.lang.mutable.MutableBoolean;
 import org.junit.Before;
-import org.sonar.batch.cache.WSLoader;
 import org.junit.Test;
+import org.sonar.batch.cache.WSLoader;
+import org.sonar.batch.cache.WSLoaderResult;
+import org.sonar.batch.protocol.input.GlobalRepositories;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
 
 public class DefaultGlobalRepositoriesLoaderTest {
-  private static final String BATCH_GLOBAL_URL = "/batch/global";
+  private static final String BATCH_GLOBAL_URL = "/scanner/global";
   private WSLoader wsLoader;
   private WSLoaderResult<String> result;
   private DefaultGlobalRepositoriesLoader globalRepositoryLoader;
index 3d2b9d18937baa774cc4f112522d334997145f4d..19be82675cc591413de59e0fbb57203071ba948c 100644 (file)
  */
 package org.sonar.batch.repository;
 
-import org.sonar.batch.cache.WSLoaderResult;
-
-import org.sonar.batch.analysis.DefaultAnalysisMode;
-import org.sonar.batch.cache.WSLoader;
-import org.apache.commons.lang.mutable.MutableBoolean;
-import org.apache.commons.io.IOUtils;
-
 import java.io.IOException;
 import java.util.Date;
-
-import static org.assertj.core.api.Assertions.assertThat;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.mutable.MutableBoolean;
 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.utils.MessageException;
+import org.sonar.batch.analysis.DefaultAnalysisMode;
+import org.sonar.batch.cache.WSLoader;
+import org.sonar.batch.cache.WSLoaderResult;
 import org.sonar.batch.protocol.input.ProjectRepositories;
 import org.sonar.batch.protocol.input.QProfile;
+
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -69,11 +67,11 @@ public class DefaultProjectRepositoriesLoaderTest {
     project = ProjectDefinition.create().setKey("foo");
     when(analysisMode.isIssues()).thenReturn(false);
     loader.load(project.getKeyWithBranch(), null, null);
-    verify(wsLoader).loadString("/batch/project?key=foo&preview=false");
+    verify(wsLoader).loadString("/scanner/project?key=foo&preview=false");
 
     when(analysisMode.isIssues()).thenReturn(true);
     loader.load(project.getKeyWithBranch(), null, null);
-    verify(wsLoader).loadString("/batch/project?key=foo&preview=true");
+    verify(wsLoader).loadString("/scanner/project?key=foo&preview=true");
   }
 
   @Test
@@ -96,7 +94,7 @@ public class DefaultProjectRepositoriesLoaderTest {
     addQualityProfile();
     project = ProjectDefinition.create().setKey("foo bàr");
     loader.load(project.getKeyWithBranch(), null, null);
-    verify(wsLoader).loadString("/batch/project?key=foo+b%C3%A0r&preview=false");
+    verify(wsLoader).loadString("/scanner/project?key=foo+b%C3%A0r&preview=false");
   }
 
   @Test
@@ -104,7 +102,7 @@ public class DefaultProjectRepositoriesLoaderTest {
     addQualityProfile();
     project = ProjectDefinition.create().setKey("foo");
     loader.load(project.getKeyWithBranch(), "my-profile#2", null);
-    verify(wsLoader).loadString("/batch/project?key=foo&profile=my-profile%232&preview=false");
+    verify(wsLoader).loadString("/scanner/project?key=foo&profile=my-profile%232&preview=false");
   }
 
   @Test
index 04f5dda2325a5fbb9f38f0f9da77794ba2afd839..07dab6b0ab5ffb9672c7b0c38ad1bbd080c78b34 100644 (file)
@@ -52,7 +52,7 @@ public class DefaultServerIssuesLoaderTest {
   @Test
   public void loadFromWs() throws Exception {
     ByteSource bs = mock(ByteSource.class);
-    when(wsLoader.loadSource("/batch/issues?key=foo")).thenReturn(new WSLoaderResult<>(bs, true));
+    when(wsLoader.loadSource("/scanner/issues?key=foo")).thenReturn(new WSLoaderResult<>(bs, true));
 
     ByteArrayOutputStream bos = new ByteArrayOutputStream();
 
@@ -80,7 +80,7 @@ public class DefaultServerIssuesLoaderTest {
   public void testError() throws IOException {
     ByteSource source = mock(ByteSource.class);
     when(source.openBufferedStream()).thenThrow(IOException.class);
-    when(wsLoader.loadSource("/batch/issues?key=foo")).thenReturn(new WSLoaderResult<ByteSource>(source, true));
+    when(wsLoader.loadSource("/scanner/issues?key=foo")).thenReturn(new WSLoaderResult<ByteSource>(source, true));
     loader.load("foo", mock(Function.class));
   }
 }
index 5410f18a7c17d63b5ec16065e75bc459a85ebebf..a449f57837dcb446543c3d55ca6dd58e008f166f 100644 (file)
@@ -69,7 +69,7 @@ public class UserRepositoryLoaderTest {
   public void testLoad() throws IOException {
     Map<String, String> userMap = ImmutableMap.of("fmallet", "Freddy Mallet", "sbrandhof", "Simon");
     WSLoaderResult<ByteSource> res = new WSLoaderResult<>(createUsersMock(userMap), true);
-    when(wsLoader.loadSource("/batch/users?logins=fmallet,sbrandhof")).thenReturn(res);
+    when(wsLoader.loadSource("/scanner/users?logins=fmallet,sbrandhof")).thenReturn(res);
 
     assertThat(userRepo.load(Arrays.asList("fmallet", "sbrandhof"))).extracting("login", "name").containsOnly(tuple("fmallet", "Freddy Mallet"), tuple("sbrandhof", "Simon"));
   }
@@ -90,7 +90,7 @@ public class UserRepositoryLoaderTest {
   @Test
   public void testLoadSingleUser() throws IOException {
     WSLoaderResult<ByteSource> res = new WSLoaderResult<>(createUsersMock(ImmutableMap.of("fmallet", "Freddy Mallet")), true);
-    when(wsLoader.loadSource("/batch/users?logins=fmallet")).thenReturn(res);
+    when(wsLoader.loadSource("/scanner/users?logins=fmallet")).thenReturn(res);
 
     assertThat(userRepo.load("fmallet").getName()).isEqualTo("Freddy Mallet");
   }
@@ -113,7 +113,7 @@ public class UserRepositoryLoaderTest {
 
     WSLoaderResult<ByteSource> res = new WSLoaderResult<>(source, true);
 
-    when(wsLoader.loadSource("/batch/users?logins=fmallet,sbrandhof")).thenReturn(res);
+    when(wsLoader.loadSource("/scanner/users?logins=fmallet,sbrandhof")).thenReturn(res);
 
     InputStream errorInputStream = mock(InputStream.class);
     Mockito.doThrow(IOException.class).when(errorInputStream).read();
diff --git a/sonar-ws/src/main/gen-java/org/sonarqube/ws/WsBatch.java b/sonar-ws/src/main/gen-java/org/sonarqube/ws/WsBatch.java
deleted file mode 100644 (file)
index 991ac25..0000000
+++ /dev/null
@@ -1,2417 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: ws-batch.proto
-
-package org.sonarqube.ws;
-
-public final class WsBatch {
-  private WsBatch() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistry registry) {
-  }
-  public interface WsProjectResponseOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:sonarqube.ws.batch.WsProjectResponse)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>optional int64 timestamp = 1;</code>
-     */
-    boolean hasTimestamp();
-    /**
-     * <code>optional int64 timestamp = 1;</code>
-     */
-    long getTimestamp();
-
-    /**
-     * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.Settings&gt; settingsByModule = 2;</code>
-     */
-    java.util.Map<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings>
-    getSettingsByModule();
-
-    /**
-     * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileDataByPath&gt; fileDataByModuleAndPatch = 3;</code>
-     */
-    java.util.Map<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath>
-    getFileDataByModuleAndPatch();
-
-    /**
-     * <code>optional int64 lastAnalysisDate = 4;</code>
-     */
-    boolean hasLastAnalysisDate();
-    /**
-     * <code>optional int64 lastAnalysisDate = 4;</code>
-     */
-    long getLastAnalysisDate();
-  }
-  /**
-   * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse}
-   *
-   * <pre>
-   * WS api/batch/project
-   * </pre>
-   */
-  public  static final class WsProjectResponse extends
-      com.google.protobuf.GeneratedMessage implements
-      // @@protoc_insertion_point(message_implements:sonarqube.ws.batch.WsProjectResponse)
-      WsProjectResponseOrBuilder {
-    // Use WsProjectResponse.newBuilder() to construct.
-    private WsProjectResponse(com.google.protobuf.GeneratedMessage.Builder builder) {
-      super(builder);
-    }
-    private WsProjectResponse() {
-      timestamp_ = 0L;
-      lastAnalysisDate_ = 0L;
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private WsProjectResponse(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry) {
-      this();
-      int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-            case 8: {
-              bitField0_ |= 0x00000001;
-              timestamp_ = input.readInt64();
-              break;
-            }
-            case 18: {
-              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
-                settingsByModule_ = com.google.protobuf.MapField.newMapField(
-                    SettingsByModuleDefaultEntryHolder.defaultEntry);
-                mutable_bitField0_ |= 0x00000002;
-              }
-              com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings>
-              settingsByModule = input.readMessage(
-                  SettingsByModuleDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
-              settingsByModule_.getMutableMap().put(settingsByModule.getKey(), settingsByModule.getValue());
-              break;
-            }
-            case 26: {
-              if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
-                fileDataByModuleAndPatch_ = com.google.protobuf.MapField.newMapField(
-                    FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry);
-                mutable_bitField0_ |= 0x00000004;
-              }
-              com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath>
-              fileDataByModuleAndPatch = input.readMessage(
-                  FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
-              fileDataByModuleAndPatch_.getMutableMap().put(fileDataByModuleAndPatch.getKey(), fileDataByModuleAndPatch.getValue());
-              break;
-            }
-            case 32: {
-              bitField0_ |= 0x00000002;
-              lastAnalysisDate_ = input.readInt64();
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw new RuntimeException(e.setUnfinishedMessage(this));
-      } catch (java.io.IOException e) {
-        throw new RuntimeException(
-            new com.google.protobuf.InvalidProtocolBufferException(
-                e.getMessage()).setUnfinishedMessage(this));
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor;
-    }
-
-    @SuppressWarnings({"rawtypes"})
-    protected com.google.protobuf.MapField internalGetMapField(
-        int number) {
-      switch (number) {
-        case 2:
-          return internalGetSettingsByModule();
-        case 3:
-          return internalGetFileDataByModuleAndPatch();
-        default:
-          throw new RuntimeException(
-              "Invalid map field number: " + number);
-      }
-    }
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              org.sonarqube.ws.WsBatch.WsProjectResponse.class, org.sonarqube.ws.WsBatch.WsProjectResponse.Builder.class);
-    }
-
-    public interface SettingsOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:sonarqube.ws.batch.WsProjectResponse.Settings)
-        com.google.protobuf.MessageOrBuilder {
-
-      /**
-       * <code>map&lt;string, string&gt; settings = 1;</code>
-       */
-      java.util.Map<java.lang.String, java.lang.String>
-      getSettings();
-    }
-    /**
-     * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse.Settings}
-     */
-    public  static final class Settings extends
-        com.google.protobuf.GeneratedMessage implements
-        // @@protoc_insertion_point(message_implements:sonarqube.ws.batch.WsProjectResponse.Settings)
-        SettingsOrBuilder {
-      // Use Settings.newBuilder() to construct.
-      private Settings(com.google.protobuf.GeneratedMessage.Builder builder) {
-        super(builder);
-      }
-      private Settings() {
-      }
-
-      @java.lang.Override
-      public final com.google.protobuf.UnknownFieldSet
-      getUnknownFields() {
-        return this.unknownFields;
-      }
-      private Settings(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry) {
-        this();
-        int mutable_bitField0_ = 0;
-        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-            com.google.protobuf.UnknownFieldSet.newBuilder();
-        try {
-          boolean done = false;
-          while (!done) {
-            int tag = input.readTag();
-            switch (tag) {
-              case 0:
-                done = true;
-                break;
-              default: {
-                if (!parseUnknownField(input, unknownFields,
-                                       extensionRegistry, tag)) {
-                  done = true;
-                }
-                break;
-              }
-              case 10: {
-                if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-                  settings_ = com.google.protobuf.MapField.newMapField(
-                      SettingsDefaultEntryHolder.defaultEntry);
-                  mutable_bitField0_ |= 0x00000001;
-                }
-                com.google.protobuf.MapEntry<java.lang.String, java.lang.String>
-                settings = input.readMessage(
-                    SettingsDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
-                settings_.getMutableMap().put(settings.getKey(), settings.getValue());
-                break;
-              }
-            }
-          }
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          throw new RuntimeException(e.setUnfinishedMessage(this));
-        } catch (java.io.IOException e) {
-          throw new RuntimeException(
-              new com.google.protobuf.InvalidProtocolBufferException(
-                  e.getMessage()).setUnfinishedMessage(this));
-        } finally {
-          this.unknownFields = unknownFields.build();
-          makeExtensionsImmutable();
-        }
-      }
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor;
-      }
-
-      @SuppressWarnings({"rawtypes"})
-      protected com.google.protobuf.MapField internalGetMapField(
-          int number) {
-        switch (number) {
-          case 1:
-            return internalGetSettings();
-          default:
-            throw new RuntimeException(
-                "Invalid map field number: " + number);
-        }
-      }
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.sonarqube.ws.WsBatch.WsProjectResponse.Settings.class, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings.Builder.class);
-      }
-
-      public static final int SETTINGS_FIELD_NUMBER = 1;
-      private static final class SettingsDefaultEntryHolder {
-        static final com.google.protobuf.MapEntry<
-            java.lang.String, java.lang.String> defaultEntry =
-                com.google.protobuf.MapEntry
-                .<java.lang.String, java.lang.String>newDefaultInstance(
-                    org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_SettingsEntry_descriptor, 
-                    com.google.protobuf.WireFormat.FieldType.STRING,
-                    "",
-                    com.google.protobuf.WireFormat.FieldType.STRING,
-                    "");
-      }
-      private com.google.protobuf.MapField<
-          java.lang.String, java.lang.String> settings_;
-      private com.google.protobuf.MapField<java.lang.String, java.lang.String>
-      internalGetSettings() {
-        if (settings_ == null) {
-          return com.google.protobuf.MapField.emptyMapField(
-              SettingsDefaultEntryHolder.defaultEntry);
-       }
-        return settings_;
-      }
-      /**
-       * <code>map&lt;string, string&gt; settings = 1;</code>
-       */
-
-      public java.util.Map<java.lang.String, java.lang.String> getSettings() {
-        return internalGetSettings().getMap();
-      }
-
-      private byte memoizedIsInitialized = -1;
-      public final boolean isInitialized() {
-        byte isInitialized = memoizedIsInitialized;
-        if (isInitialized == 1) return true;
-        if (isInitialized == 0) return false;
-
-        memoizedIsInitialized = 1;
-        return true;
-      }
-
-      public void writeTo(com.google.protobuf.CodedOutputStream output)
-                          throws java.io.IOException {
-        for (java.util.Map.Entry<java.lang.String, java.lang.String> entry
-             : internalGetSettings().getMap().entrySet()) {
-          com.google.protobuf.MapEntry<java.lang.String, java.lang.String>
-          settings = SettingsDefaultEntryHolder.defaultEntry.newBuilderForType()
-              .setKey(entry.getKey())
-              .setValue(entry.getValue())
-              .build();
-          output.writeMessage(1, settings);
-        }
-        unknownFields.writeTo(output);
-      }
-
-      private int memoizedSerializedSize = -1;
-      public int getSerializedSize() {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-
-        size = 0;
-        for (java.util.Map.Entry<java.lang.String, java.lang.String> entry
-             : internalGetSettings().getMap().entrySet()) {
-          com.google.protobuf.MapEntry<java.lang.String, java.lang.String>
-          settings = SettingsDefaultEntryHolder.defaultEntry.newBuilderForType()
-              .setKey(entry.getKey())
-              .setValue(entry.getValue())
-              .build();
-          size += com.google.protobuf.CodedOutputStream
-              .computeMessageSize(1, settings);
-        }
-        size += unknownFields.getSerializedSize();
-        memoizedSerializedSize = size;
-        return size;
-      }
-
-      private static final long serialVersionUID = 0L;
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.Settings parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.Settings parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data, extensionRegistry);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.Settings parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.Settings parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data, extensionRegistry);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.Settings parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.Settings parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input, extensionRegistry);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.Settings parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return PARSER.parseDelimitedFrom(input);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.Settings parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return PARSER.parseDelimitedFrom(input, extensionRegistry);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.Settings parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.Settings parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input, extensionRegistry);
-      }
-
-      public Builder newBuilderForType() { return newBuilder(); }
-      public static Builder newBuilder() {
-        return DEFAULT_INSTANCE.toBuilder();
-      }
-      public static Builder newBuilder(org.sonarqube.ws.WsBatch.WsProjectResponse.Settings prototype) {
-        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
-      }
-      public Builder toBuilder() {
-        return this == DEFAULT_INSTANCE
-            ? new Builder() : new Builder().mergeFrom(this);
-      }
-
-      @java.lang.Override
-      protected Builder newBuilderForType(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        Builder builder = new Builder(parent);
-        return builder;
-      }
-      /**
-       * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse.Settings}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessage.Builder<Builder> implements
-          // @@protoc_insertion_point(builder_implements:sonarqube.ws.batch.WsProjectResponse.Settings)
-          org.sonarqube.ws.WsBatch.WsProjectResponse.SettingsOrBuilder {
-        public static final com.google.protobuf.Descriptors.Descriptor
-            getDescriptor() {
-          return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor;
-        }
-
-        @SuppressWarnings({"rawtypes"})
-        protected com.google.protobuf.MapField internalGetMapField(
-            int number) {
-          switch (number) {
-            case 1:
-              return internalGetSettings();
-            default:
-              throw new RuntimeException(
-                  "Invalid map field number: " + number);
-          }
-        }
-        @SuppressWarnings({"rawtypes"})
-        protected com.google.protobuf.MapField internalGetMutableMapField(
-            int number) {
-          switch (number) {
-            case 1:
-              return internalGetMutableSettings();
-            default:
-              throw new RuntimeException(
-                  "Invalid map field number: " + number);
-          }
-        }
-        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-            internalGetFieldAccessorTable() {
-          return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_fieldAccessorTable
-              .ensureFieldAccessorsInitialized(
-                  org.sonarqube.ws.WsBatch.WsProjectResponse.Settings.class, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings.Builder.class);
-        }
-
-        // Construct using org.sonarqube.ws.WsBatch.WsProjectResponse.Settings.newBuilder()
-        private Builder() {
-          maybeForceBuilderInitialization();
-        }
-
-        private Builder(
-            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-          super(parent);
-          maybeForceBuilderInitialization();
-        }
-        private void maybeForceBuilderInitialization() {
-          if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-          }
-        }
-        public Builder clear() {
-          super.clear();
-          internalGetMutableSettings().clear();
-          return this;
-        }
-
-        public com.google.protobuf.Descriptors.Descriptor
-            getDescriptorForType() {
-          return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor;
-        }
-
-        public org.sonarqube.ws.WsBatch.WsProjectResponse.Settings getDefaultInstanceForType() {
-          return org.sonarqube.ws.WsBatch.WsProjectResponse.Settings.getDefaultInstance();
-        }
-
-        public org.sonarqube.ws.WsBatch.WsProjectResponse.Settings build() {
-          org.sonarqube.ws.WsBatch.WsProjectResponse.Settings result = buildPartial();
-          if (!result.isInitialized()) {
-            throw newUninitializedMessageException(result);
-          }
-          return result;
-        }
-
-        public org.sonarqube.ws.WsBatch.WsProjectResponse.Settings buildPartial() {
-          org.sonarqube.ws.WsBatch.WsProjectResponse.Settings result = new org.sonarqube.ws.WsBatch.WsProjectResponse.Settings(this);
-          int from_bitField0_ = bitField0_;
-          result.settings_ = internalGetSettings();
-          result.settings_.makeImmutable();
-          onBuilt();
-          return result;
-        }
-
-        public Builder mergeFrom(com.google.protobuf.Message other) {
-          if (other instanceof org.sonarqube.ws.WsBatch.WsProjectResponse.Settings) {
-            return mergeFrom((org.sonarqube.ws.WsBatch.WsProjectResponse.Settings)other);
-          } else {
-            super.mergeFrom(other);
-            return this;
-          }
-        }
-
-        public Builder mergeFrom(org.sonarqube.ws.WsBatch.WsProjectResponse.Settings other) {
-          if (other == org.sonarqube.ws.WsBatch.WsProjectResponse.Settings.getDefaultInstance()) return this;
-          internalGetMutableSettings().mergeFrom(
-              other.internalGetSettings());
-          this.mergeUnknownFields(other.unknownFields);
-          onChanged();
-          return this;
-        }
-
-        public final boolean isInitialized() {
-          return true;
-        }
-
-        public Builder mergeFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          org.sonarqube.ws.WsBatch.WsProjectResponse.Settings parsedMessage = null;
-          try {
-            parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            parsedMessage = (org.sonarqube.ws.WsBatch.WsProjectResponse.Settings) e.getUnfinishedMessage();
-            throw e;
-          } finally {
-            if (parsedMessage != null) {
-              mergeFrom(parsedMessage);
-            }
-          }
-          return this;
-        }
-        private int bitField0_;
-
-        private com.google.protobuf.MapField<
-            java.lang.String, java.lang.String> settings_;
-        private com.google.protobuf.MapField<java.lang.String, java.lang.String>
-        internalGetSettings() {
-          if (settings_ == null) {
-            return com.google.protobuf.MapField.emptyMapField(
-                SettingsDefaultEntryHolder.defaultEntry);
-         }
-          return settings_;
-        }
-        private com.google.protobuf.MapField<java.lang.String, java.lang.String>
-        internalGetMutableSettings() {
-          onChanged();;
-          if (settings_ == null) {
-            settings_ = com.google.protobuf.MapField.newMapField(
-                SettingsDefaultEntryHolder.defaultEntry);
-          }
-          if (!settings_.isMutable()) {
-            settings_ = settings_.copy();
-          }
-          return settings_;
-        }
-        /**
-         * <code>map&lt;string, string&gt; settings = 1;</code>
-         */
-        public java.util.Map<java.lang.String, java.lang.String> getSettings() {
-          return internalGetSettings().getMap();
-        }
-        /**
-         * <code>map&lt;string, string&gt; settings = 1;</code>
-         */
-        public java.util.Map<java.lang.String, java.lang.String>
-        getMutableSettings() {
-          return internalGetMutableSettings().getMutableMap();
-        }
-
-        // @@protoc_insertion_point(builder_scope:sonarqube.ws.batch.WsProjectResponse.Settings)
-      }
-
-      // @@protoc_insertion_point(class_scope:sonarqube.ws.batch.WsProjectResponse.Settings)
-      private static final org.sonarqube.ws.WsBatch.WsProjectResponse.Settings DEFAULT_INSTANCE;
-      static {
-        DEFAULT_INSTANCE = new org.sonarqube.ws.WsBatch.WsProjectResponse.Settings();
-      }
-
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.Settings getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      public static final com.google.protobuf.Parser<Settings> PARSER =
-          new com.google.protobuf.AbstractParser<Settings>() {
-        public Settings parsePartialFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          try {
-            return new Settings(input, extensionRegistry);
-          } catch (RuntimeException e) {
-            if (e.getCause() instanceof
-                com.google.protobuf.InvalidProtocolBufferException) {
-              throw (com.google.protobuf.InvalidProtocolBufferException)
-                  e.getCause();
-            }
-            throw e;
-          }
-        }
-      };
-
-      @java.lang.Override
-      public com.google.protobuf.Parser<Settings> getParserForType() {
-        return PARSER;
-      }
-
-      public org.sonarqube.ws.WsBatch.WsProjectResponse.Settings getDefaultInstanceForType() {
-        return DEFAULT_INSTANCE;
-      }
-
-    }
-
-    public interface FileDataByPathOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:sonarqube.ws.batch.WsProjectResponse.FileDataByPath)
-        com.google.protobuf.MessageOrBuilder {
-
-      /**
-       * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileData&gt; FileDataByPath = 1;</code>
-       */
-      java.util.Map<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData>
-      getFileDataByPath();
-    }
-    /**
-     * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse.FileDataByPath}
-     */
-    public  static final class FileDataByPath extends
-        com.google.protobuf.GeneratedMessage implements
-        // @@protoc_insertion_point(message_implements:sonarqube.ws.batch.WsProjectResponse.FileDataByPath)
-        FileDataByPathOrBuilder {
-      // Use FileDataByPath.newBuilder() to construct.
-      private FileDataByPath(com.google.protobuf.GeneratedMessage.Builder builder) {
-        super(builder);
-      }
-      private FileDataByPath() {
-      }
-
-      @java.lang.Override
-      public final com.google.protobuf.UnknownFieldSet
-      getUnknownFields() {
-        return this.unknownFields;
-      }
-      private FileDataByPath(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry) {
-        this();
-        int mutable_bitField0_ = 0;
-        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-            com.google.protobuf.UnknownFieldSet.newBuilder();
-        try {
-          boolean done = false;
-          while (!done) {
-            int tag = input.readTag();
-            switch (tag) {
-              case 0:
-                done = true;
-                break;
-              default: {
-                if (!parseUnknownField(input, unknownFields,
-                                       extensionRegistry, tag)) {
-                  done = true;
-                }
-                break;
-              }
-              case 10: {
-                if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-                  fileDataByPath_ = com.google.protobuf.MapField.newMapField(
-                      FileDataByPathDefaultEntryHolder.defaultEntry);
-                  mutable_bitField0_ |= 0x00000001;
-                }
-                com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData>
-                fileDataByPath = input.readMessage(
-                    FileDataByPathDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
-                fileDataByPath_.getMutableMap().put(fileDataByPath.getKey(), fileDataByPath.getValue());
-                break;
-              }
-            }
-          }
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          throw new RuntimeException(e.setUnfinishedMessage(this));
-        } catch (java.io.IOException e) {
-          throw new RuntimeException(
-              new com.google.protobuf.InvalidProtocolBufferException(
-                  e.getMessage()).setUnfinishedMessage(this));
-        } finally {
-          this.unknownFields = unknownFields.build();
-          makeExtensionsImmutable();
-        }
-      }
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor;
-      }
-
-      @SuppressWarnings({"rawtypes"})
-      protected com.google.protobuf.MapField internalGetMapField(
-          int number) {
-        switch (number) {
-          case 1:
-            return internalGetFileDataByPath();
-          default:
-            throw new RuntimeException(
-                "Invalid map field number: " + number);
-        }
-      }
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath.class, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath.Builder.class);
-      }
-
-      public static final int FILEDATABYPATH_FIELD_NUMBER = 1;
-      private static final class FileDataByPathDefaultEntryHolder {
-        static final com.google.protobuf.MapEntry<
-            java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData> defaultEntry =
-                com.google.protobuf.MapEntry
-                .<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData>newDefaultInstance(
-                    org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_FileDataByPathEntry_descriptor, 
-                    com.google.protobuf.WireFormat.FieldType.STRING,
-                    "",
-                    com.google.protobuf.WireFormat.FieldType.MESSAGE,
-                    org.sonarqube.ws.WsBatch.WsProjectResponse.FileData.getDefaultInstance());
-      }
-      private com.google.protobuf.MapField<
-          java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData> fileDataByPath_;
-      private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData>
-      internalGetFileDataByPath() {
-        if (fileDataByPath_ == null) {
-          return com.google.protobuf.MapField.emptyMapField(
-              FileDataByPathDefaultEntryHolder.defaultEntry);
-       }
-        return fileDataByPath_;
-      }
-      /**
-       * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileData&gt; FileDataByPath = 1;</code>
-       */
-
-      public java.util.Map<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData> getFileDataByPath() {
-        return internalGetFileDataByPath().getMap();
-      }
-
-      private byte memoizedIsInitialized = -1;
-      public final boolean isInitialized() {
-        byte isInitialized = memoizedIsInitialized;
-        if (isInitialized == 1) return true;
-        if (isInitialized == 0) return false;
-
-        memoizedIsInitialized = 1;
-        return true;
-      }
-
-      public void writeTo(com.google.protobuf.CodedOutputStream output)
-                          throws java.io.IOException {
-        for (java.util.Map.Entry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData> entry
-             : internalGetFileDataByPath().getMap().entrySet()) {
-          com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData>
-          fileDataByPath = FileDataByPathDefaultEntryHolder.defaultEntry.newBuilderForType()
-              .setKey(entry.getKey())
-              .setValue(entry.getValue())
-              .build();
-          output.writeMessage(1, fileDataByPath);
-        }
-        unknownFields.writeTo(output);
-      }
-
-      private int memoizedSerializedSize = -1;
-      public int getSerializedSize() {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-
-        size = 0;
-        for (java.util.Map.Entry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData> entry
-             : internalGetFileDataByPath().getMap().entrySet()) {
-          com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData>
-          fileDataByPath = FileDataByPathDefaultEntryHolder.defaultEntry.newBuilderForType()
-              .setKey(entry.getKey())
-              .setValue(entry.getValue())
-              .build();
-          size += com.google.protobuf.CodedOutputStream
-              .computeMessageSize(1, fileDataByPath);
-        }
-        size += unknownFields.getSerializedSize();
-        memoizedSerializedSize = size;
-        return size;
-      }
-
-      private static final long serialVersionUID = 0L;
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data, extensionRegistry);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data, extensionRegistry);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input, extensionRegistry);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return PARSER.parseDelimitedFrom(input);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return PARSER.parseDelimitedFrom(input, extensionRegistry);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input, extensionRegistry);
-      }
-
-      public Builder newBuilderForType() { return newBuilder(); }
-      public static Builder newBuilder() {
-        return DEFAULT_INSTANCE.toBuilder();
-      }
-      public static Builder newBuilder(org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath prototype) {
-        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
-      }
-      public Builder toBuilder() {
-        return this == DEFAULT_INSTANCE
-            ? new Builder() : new Builder().mergeFrom(this);
-      }
-
-      @java.lang.Override
-      protected Builder newBuilderForType(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        Builder builder = new Builder(parent);
-        return builder;
-      }
-      /**
-       * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse.FileDataByPath}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessage.Builder<Builder> implements
-          // @@protoc_insertion_point(builder_implements:sonarqube.ws.batch.WsProjectResponse.FileDataByPath)
-          org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPathOrBuilder {
-        public static final com.google.protobuf.Descriptors.Descriptor
-            getDescriptor() {
-          return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor;
-        }
-
-        @SuppressWarnings({"rawtypes"})
-        protected com.google.protobuf.MapField internalGetMapField(
-            int number) {
-          switch (number) {
-            case 1:
-              return internalGetFileDataByPath();
-            default:
-              throw new RuntimeException(
-                  "Invalid map field number: " + number);
-          }
-        }
-        @SuppressWarnings({"rawtypes"})
-        protected com.google.protobuf.MapField internalGetMutableMapField(
-            int number) {
-          switch (number) {
-            case 1:
-              return internalGetMutableFileDataByPath();
-            default:
-              throw new RuntimeException(
-                  "Invalid map field number: " + number);
-          }
-        }
-        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-            internalGetFieldAccessorTable() {
-          return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_fieldAccessorTable
-              .ensureFieldAccessorsInitialized(
-                  org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath.class, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath.Builder.class);
-        }
-
-        // Construct using org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath.newBuilder()
-        private Builder() {
-          maybeForceBuilderInitialization();
-        }
-
-        private Builder(
-            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-          super(parent);
-          maybeForceBuilderInitialization();
-        }
-        private void maybeForceBuilderInitialization() {
-          if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-          }
-        }
-        public Builder clear() {
-          super.clear();
-          internalGetMutableFileDataByPath().clear();
-          return this;
-        }
-
-        public com.google.protobuf.Descriptors.Descriptor
-            getDescriptorForType() {
-          return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor;
-        }
-
-        public org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath getDefaultInstanceForType() {
-          return org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath.getDefaultInstance();
-        }
-
-        public org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath build() {
-          org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath result = buildPartial();
-          if (!result.isInitialized()) {
-            throw newUninitializedMessageException(result);
-          }
-          return result;
-        }
-
-        public org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath buildPartial() {
-          org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath result = new org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath(this);
-          int from_bitField0_ = bitField0_;
-          result.fileDataByPath_ = internalGetFileDataByPath();
-          result.fileDataByPath_.makeImmutable();
-          onBuilt();
-          return result;
-        }
-
-        public Builder mergeFrom(com.google.protobuf.Message other) {
-          if (other instanceof org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath) {
-            return mergeFrom((org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath)other);
-          } else {
-            super.mergeFrom(other);
-            return this;
-          }
-        }
-
-        public Builder mergeFrom(org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath other) {
-          if (other == org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath.getDefaultInstance()) return this;
-          internalGetMutableFileDataByPath().mergeFrom(
-              other.internalGetFileDataByPath());
-          this.mergeUnknownFields(other.unknownFields);
-          onChanged();
-          return this;
-        }
-
-        public final boolean isInitialized() {
-          return true;
-        }
-
-        public Builder mergeFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath parsedMessage = null;
-          try {
-            parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            parsedMessage = (org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath) e.getUnfinishedMessage();
-            throw e;
-          } finally {
-            if (parsedMessage != null) {
-              mergeFrom(parsedMessage);
-            }
-          }
-          return this;
-        }
-        private int bitField0_;
-
-        private com.google.protobuf.MapField<
-            java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData> fileDataByPath_;
-        private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData>
-        internalGetFileDataByPath() {
-          if (fileDataByPath_ == null) {
-            return com.google.protobuf.MapField.emptyMapField(
-                FileDataByPathDefaultEntryHolder.defaultEntry);
-         }
-          return fileDataByPath_;
-        }
-        private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData>
-        internalGetMutableFileDataByPath() {
-          onChanged();;
-          if (fileDataByPath_ == null) {
-            fileDataByPath_ = com.google.protobuf.MapField.newMapField(
-                FileDataByPathDefaultEntryHolder.defaultEntry);
-          }
-          if (!fileDataByPath_.isMutable()) {
-            fileDataByPath_ = fileDataByPath_.copy();
-          }
-          return fileDataByPath_;
-        }
-        /**
-         * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileData&gt; FileDataByPath = 1;</code>
-         */
-        public java.util.Map<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData> getFileDataByPath() {
-          return internalGetFileDataByPath().getMap();
-        }
-        /**
-         * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileData&gt; FileDataByPath = 1;</code>
-         */
-        public java.util.Map<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData>
-        getMutableFileDataByPath() {
-          return internalGetMutableFileDataByPath().getMutableMap();
-        }
-
-        // @@protoc_insertion_point(builder_scope:sonarqube.ws.batch.WsProjectResponse.FileDataByPath)
-      }
-
-      // @@protoc_insertion_point(class_scope:sonarqube.ws.batch.WsProjectResponse.FileDataByPath)
-      private static final org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath DEFAULT_INSTANCE;
-      static {
-        DEFAULT_INSTANCE = new org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath();
-      }
-
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      public static final com.google.protobuf.Parser<FileDataByPath> PARSER =
-          new com.google.protobuf.AbstractParser<FileDataByPath>() {
-        public FileDataByPath parsePartialFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          try {
-            return new FileDataByPath(input, extensionRegistry);
-          } catch (RuntimeException e) {
-            if (e.getCause() instanceof
-                com.google.protobuf.InvalidProtocolBufferException) {
-              throw (com.google.protobuf.InvalidProtocolBufferException)
-                  e.getCause();
-            }
-            throw e;
-          }
-        }
-      };
-
-      @java.lang.Override
-      public com.google.protobuf.Parser<FileDataByPath> getParserForType() {
-        return PARSER;
-      }
-
-      public org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath getDefaultInstanceForType() {
-        return DEFAULT_INSTANCE;
-      }
-
-    }
-
-    public interface FileDataOrBuilder extends
-        // @@protoc_insertion_point(interface_extends:sonarqube.ws.batch.WsProjectResponse.FileData)
-        com.google.protobuf.MessageOrBuilder {
-
-      /**
-       * <code>optional string hash = 1;</code>
-       */
-      boolean hasHash();
-      /**
-       * <code>optional string hash = 1;</code>
-       */
-      java.lang.String getHash();
-      /**
-       * <code>optional string hash = 1;</code>
-       */
-      com.google.protobuf.ByteString
-          getHashBytes();
-
-      /**
-       * <code>optional string revision = 2;</code>
-       */
-      boolean hasRevision();
-      /**
-       * <code>optional string revision = 2;</code>
-       */
-      java.lang.String getRevision();
-      /**
-       * <code>optional string revision = 2;</code>
-       */
-      com.google.protobuf.ByteString
-          getRevisionBytes();
-    }
-    /**
-     * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse.FileData}
-     */
-    public  static final class FileData extends
-        com.google.protobuf.GeneratedMessage implements
-        // @@protoc_insertion_point(message_implements:sonarqube.ws.batch.WsProjectResponse.FileData)
-        FileDataOrBuilder {
-      // Use FileData.newBuilder() to construct.
-      private FileData(com.google.protobuf.GeneratedMessage.Builder builder) {
-        super(builder);
-      }
-      private FileData() {
-        hash_ = "";
-        revision_ = "";
-      }
-
-      @java.lang.Override
-      public final com.google.protobuf.UnknownFieldSet
-      getUnknownFields() {
-        return this.unknownFields;
-      }
-      private FileData(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry) {
-        this();
-        int mutable_bitField0_ = 0;
-        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-            com.google.protobuf.UnknownFieldSet.newBuilder();
-        try {
-          boolean done = false;
-          while (!done) {
-            int tag = input.readTag();
-            switch (tag) {
-              case 0:
-                done = true;
-                break;
-              default: {
-                if (!parseUnknownField(input, unknownFields,
-                                       extensionRegistry, tag)) {
-                  done = true;
-                }
-                break;
-              }
-              case 10: {
-                com.google.protobuf.ByteString bs = input.readBytes();
-                bitField0_ |= 0x00000001;
-                hash_ = bs;
-                break;
-              }
-              case 18: {
-                com.google.protobuf.ByteString bs = input.readBytes();
-                bitField0_ |= 0x00000002;
-                revision_ = bs;
-                break;
-              }
-            }
-          }
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          throw new RuntimeException(e.setUnfinishedMessage(this));
-        } catch (java.io.IOException e) {
-          throw new RuntimeException(
-              new com.google.protobuf.InvalidProtocolBufferException(
-                  e.getMessage()).setUnfinishedMessage(this));
-        } finally {
-          this.unknownFields = unknownFields.build();
-          makeExtensionsImmutable();
-        }
-      }
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.sonarqube.ws.WsBatch.WsProjectResponse.FileData.class, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData.Builder.class);
-      }
-
-      private int bitField0_;
-      public static final int HASH_FIELD_NUMBER = 1;
-      private volatile java.lang.Object hash_;
-      /**
-       * <code>optional string hash = 1;</code>
-       */
-      public boolean hasHash() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>optional string hash = 1;</code>
-       */
-      public java.lang.String getHash() {
-        java.lang.Object ref = hash_;
-        if (ref instanceof java.lang.String) {
-          return (java.lang.String) ref;
-        } else {
-          com.google.protobuf.ByteString bs = 
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          if (bs.isValidUtf8()) {
-            hash_ = s;
-          }
-          return s;
-        }
-      }
-      /**
-       * <code>optional string hash = 1;</code>
-       */
-      public com.google.protobuf.ByteString
-          getHashBytes() {
-        java.lang.Object ref = hash_;
-        if (ref instanceof java.lang.String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          hash_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-
-      public static final int REVISION_FIELD_NUMBER = 2;
-      private volatile java.lang.Object revision_;
-      /**
-       * <code>optional string revision = 2;</code>
-       */
-      public boolean hasRevision() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
-      }
-      /**
-       * <code>optional string revision = 2;</code>
-       */
-      public java.lang.String getRevision() {
-        java.lang.Object ref = revision_;
-        if (ref instanceof java.lang.String) {
-          return (java.lang.String) ref;
-        } else {
-          com.google.protobuf.ByteString bs = 
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          if (bs.isValidUtf8()) {
-            revision_ = s;
-          }
-          return s;
-        }
-      }
-      /**
-       * <code>optional string revision = 2;</code>
-       */
-      public com.google.protobuf.ByteString
-          getRevisionBytes() {
-        java.lang.Object ref = revision_;
-        if (ref instanceof java.lang.String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          revision_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-
-      private byte memoizedIsInitialized = -1;
-      public final boolean isInitialized() {
-        byte isInitialized = memoizedIsInitialized;
-        if (isInitialized == 1) return true;
-        if (isInitialized == 0) return false;
-
-        memoizedIsInitialized = 1;
-        return true;
-      }
-
-      public void writeTo(com.google.protobuf.CodedOutputStream output)
-                          throws java.io.IOException {
-        if (((bitField0_ & 0x00000001) == 0x00000001)) {
-          output.writeBytes(1, getHashBytes());
-        }
-        if (((bitField0_ & 0x00000002) == 0x00000002)) {
-          output.writeBytes(2, getRevisionBytes());
-        }
-        unknownFields.writeTo(output);
-      }
-
-      private int memoizedSerializedSize = -1;
-      public int getSerializedSize() {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-
-        size = 0;
-        if (((bitField0_ & 0x00000001) == 0x00000001)) {
-          size += com.google.protobuf.CodedOutputStream
-            .computeBytesSize(1, getHashBytes());
-        }
-        if (((bitField0_ & 0x00000002) == 0x00000002)) {
-          size += com.google.protobuf.CodedOutputStream
-            .computeBytesSize(2, getRevisionBytes());
-        }
-        size += unknownFields.getSerializedSize();
-        memoizedSerializedSize = size;
-        return size;
-      }
-
-      private static final long serialVersionUID = 0L;
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileData parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileData parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data, extensionRegistry);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileData parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileData parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data, extensionRegistry);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileData parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileData parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input, extensionRegistry);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileData parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return PARSER.parseDelimitedFrom(input);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileData parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return PARSER.parseDelimitedFrom(input, extensionRegistry);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileData parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input);
-      }
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileData parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input, extensionRegistry);
-      }
-
-      public Builder newBuilderForType() { return newBuilder(); }
-      public static Builder newBuilder() {
-        return DEFAULT_INSTANCE.toBuilder();
-      }
-      public static Builder newBuilder(org.sonarqube.ws.WsBatch.WsProjectResponse.FileData prototype) {
-        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
-      }
-      public Builder toBuilder() {
-        return this == DEFAULT_INSTANCE
-            ? new Builder() : new Builder().mergeFrom(this);
-      }
-
-      @java.lang.Override
-      protected Builder newBuilderForType(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        Builder builder = new Builder(parent);
-        return builder;
-      }
-      /**
-       * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse.FileData}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessage.Builder<Builder> implements
-          // @@protoc_insertion_point(builder_implements:sonarqube.ws.batch.WsProjectResponse.FileData)
-          org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataOrBuilder {
-        public static final com.google.protobuf.Descriptors.Descriptor
-            getDescriptor() {
-          return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_descriptor;
-        }
-
-        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-            internalGetFieldAccessorTable() {
-          return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_fieldAccessorTable
-              .ensureFieldAccessorsInitialized(
-                  org.sonarqube.ws.WsBatch.WsProjectResponse.FileData.class, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData.Builder.class);
-        }
-
-        // Construct using org.sonarqube.ws.WsBatch.WsProjectResponse.FileData.newBuilder()
-        private Builder() {
-          maybeForceBuilderInitialization();
-        }
-
-        private Builder(
-            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-          super(parent);
-          maybeForceBuilderInitialization();
-        }
-        private void maybeForceBuilderInitialization() {
-          if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-          }
-        }
-        public Builder clear() {
-          super.clear();
-          hash_ = "";
-          bitField0_ = (bitField0_ & ~0x00000001);
-          revision_ = "";
-          bitField0_ = (bitField0_ & ~0x00000002);
-          return this;
-        }
-
-        public com.google.protobuf.Descriptors.Descriptor
-            getDescriptorForType() {
-          return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_descriptor;
-        }
-
-        public org.sonarqube.ws.WsBatch.WsProjectResponse.FileData getDefaultInstanceForType() {
-          return org.sonarqube.ws.WsBatch.WsProjectResponse.FileData.getDefaultInstance();
-        }
-
-        public org.sonarqube.ws.WsBatch.WsProjectResponse.FileData build() {
-          org.sonarqube.ws.WsBatch.WsProjectResponse.FileData result = buildPartial();
-          if (!result.isInitialized()) {
-            throw newUninitializedMessageException(result);
-          }
-          return result;
-        }
-
-        public org.sonarqube.ws.WsBatch.WsProjectResponse.FileData buildPartial() {
-          org.sonarqube.ws.WsBatch.WsProjectResponse.FileData result = new org.sonarqube.ws.WsBatch.WsProjectResponse.FileData(this);
-          int from_bitField0_ = bitField0_;
-          int to_bitField0_ = 0;
-          if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-            to_bitField0_ |= 0x00000001;
-          }
-          result.hash_ = hash_;
-          if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
-            to_bitField0_ |= 0x00000002;
-          }
-          result.revision_ = revision_;
-          result.bitField0_ = to_bitField0_;
-          onBuilt();
-          return result;
-        }
-
-        public Builder mergeFrom(com.google.protobuf.Message other) {
-          if (other instanceof org.sonarqube.ws.WsBatch.WsProjectResponse.FileData) {
-            return mergeFrom((org.sonarqube.ws.WsBatch.WsProjectResponse.FileData)other);
-          } else {
-            super.mergeFrom(other);
-            return this;
-          }
-        }
-
-        public Builder mergeFrom(org.sonarqube.ws.WsBatch.WsProjectResponse.FileData other) {
-          if (other == org.sonarqube.ws.WsBatch.WsProjectResponse.FileData.getDefaultInstance()) return this;
-          if (other.hasHash()) {
-            bitField0_ |= 0x00000001;
-            hash_ = other.hash_;
-            onChanged();
-          }
-          if (other.hasRevision()) {
-            bitField0_ |= 0x00000002;
-            revision_ = other.revision_;
-            onChanged();
-          }
-          this.mergeUnknownFields(other.unknownFields);
-          onChanged();
-          return this;
-        }
-
-        public final boolean isInitialized() {
-          return true;
-        }
-
-        public Builder mergeFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          org.sonarqube.ws.WsBatch.WsProjectResponse.FileData parsedMessage = null;
-          try {
-            parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            parsedMessage = (org.sonarqube.ws.WsBatch.WsProjectResponse.FileData) e.getUnfinishedMessage();
-            throw e;
-          } finally {
-            if (parsedMessage != null) {
-              mergeFrom(parsedMessage);
-            }
-          }
-          return this;
-        }
-        private int bitField0_;
-
-        private java.lang.Object hash_ = "";
-        /**
-         * <code>optional string hash = 1;</code>
-         */
-        public boolean hasHash() {
-          return ((bitField0_ & 0x00000001) == 0x00000001);
-        }
-        /**
-         * <code>optional string hash = 1;</code>
-         */
-        public java.lang.String getHash() {
-          java.lang.Object ref = hash_;
-          if (!(ref instanceof java.lang.String)) {
-            com.google.protobuf.ByteString bs =
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              hash_ = s;
-            }
-            return s;
-          } else {
-            return (java.lang.String) ref;
-          }
-        }
-        /**
-         * <code>optional string hash = 1;</code>
-         */
-        public com.google.protobuf.ByteString
-            getHashBytes() {
-          java.lang.Object ref = hash_;
-          if (ref instanceof String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            hash_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-        /**
-         * <code>optional string hash = 1;</code>
-         */
-        public Builder setHash(
-            java.lang.String value) {
-          if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-          hash_ = value;
-          onChanged();
-          return this;
-        }
-        /**
-         * <code>optional string hash = 1;</code>
-         */
-        public Builder clearHash() {
-          bitField0_ = (bitField0_ & ~0x00000001);
-          hash_ = getDefaultInstance().getHash();
-          onChanged();
-          return this;
-        }
-        /**
-         * <code>optional string hash = 1;</code>
-         */
-        public Builder setHashBytes(
-            com.google.protobuf.ByteString value) {
-          if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-          hash_ = value;
-          onChanged();
-          return this;
-        }
-
-        private java.lang.Object revision_ = "";
-        /**
-         * <code>optional string revision = 2;</code>
-         */
-        public boolean hasRevision() {
-          return ((bitField0_ & 0x00000002) == 0x00000002);
-        }
-        /**
-         * <code>optional string revision = 2;</code>
-         */
-        public java.lang.String getRevision() {
-          java.lang.Object ref = revision_;
-          if (!(ref instanceof java.lang.String)) {
-            com.google.protobuf.ByteString bs =
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              revision_ = s;
-            }
-            return s;
-          } else {
-            return (java.lang.String) ref;
-          }
-        }
-        /**
-         * <code>optional string revision = 2;</code>
-         */
-        public com.google.protobuf.ByteString
-            getRevisionBytes() {
-          java.lang.Object ref = revision_;
-          if (ref instanceof String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            revision_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-        /**
-         * <code>optional string revision = 2;</code>
-         */
-        public Builder setRevision(
-            java.lang.String value) {
-          if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000002;
-          revision_ = value;
-          onChanged();
-          return this;
-        }
-        /**
-         * <code>optional string revision = 2;</code>
-         */
-        public Builder clearRevision() {
-          bitField0_ = (bitField0_ & ~0x00000002);
-          revision_ = getDefaultInstance().getRevision();
-          onChanged();
-          return this;
-        }
-        /**
-         * <code>optional string revision = 2;</code>
-         */
-        public Builder setRevisionBytes(
-            com.google.protobuf.ByteString value) {
-          if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000002;
-          revision_ = value;
-          onChanged();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:sonarqube.ws.batch.WsProjectResponse.FileData)
-      }
-
-      // @@protoc_insertion_point(class_scope:sonarqube.ws.batch.WsProjectResponse.FileData)
-      private static final org.sonarqube.ws.WsBatch.WsProjectResponse.FileData DEFAULT_INSTANCE;
-      static {
-        DEFAULT_INSTANCE = new org.sonarqube.ws.WsBatch.WsProjectResponse.FileData();
-      }
-
-      public static org.sonarqube.ws.WsBatch.WsProjectResponse.FileData getDefaultInstance() {
-        return DEFAULT_INSTANCE;
-      }
-
-      public static final com.google.protobuf.Parser<FileData> PARSER =
-          new com.google.protobuf.AbstractParser<FileData>() {
-        public FileData parsePartialFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          try {
-            return new FileData(input, extensionRegistry);
-          } catch (RuntimeException e) {
-            if (e.getCause() instanceof
-                com.google.protobuf.InvalidProtocolBufferException) {
-              throw (com.google.protobuf.InvalidProtocolBufferException)
-                  e.getCause();
-            }
-            throw e;
-          }
-        }
-      };
-
-      @java.lang.Override
-      public com.google.protobuf.Parser<FileData> getParserForType() {
-        return PARSER;
-      }
-
-      public org.sonarqube.ws.WsBatch.WsProjectResponse.FileData getDefaultInstanceForType() {
-        return DEFAULT_INSTANCE;
-      }
-
-    }
-
-    private int bitField0_;
-    public static final int TIMESTAMP_FIELD_NUMBER = 1;
-    private long timestamp_;
-    /**
-     * <code>optional int64 timestamp = 1;</code>
-     */
-    public boolean hasTimestamp() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
-    /**
-     * <code>optional int64 timestamp = 1;</code>
-     */
-    public long getTimestamp() {
-      return timestamp_;
-    }
-
-    public static final int SETTINGSBYMODULE_FIELD_NUMBER = 2;
-    private static final class SettingsByModuleDefaultEntryHolder {
-      static final com.google.protobuf.MapEntry<
-          java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings> defaultEntry =
-              com.google.protobuf.MapEntry
-              .<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings>newDefaultInstance(
-                  org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_SettingsByModuleEntry_descriptor, 
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "",
-                  com.google.protobuf.WireFormat.FieldType.MESSAGE,
-                  org.sonarqube.ws.WsBatch.WsProjectResponse.Settings.getDefaultInstance());
-    }
-    private com.google.protobuf.MapField<
-        java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings> settingsByModule_;
-    private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings>
-    internalGetSettingsByModule() {
-      if (settingsByModule_ == null) {
-        return com.google.protobuf.MapField.emptyMapField(
-            SettingsByModuleDefaultEntryHolder.defaultEntry);
-     }
-      return settingsByModule_;
-    }
-    /**
-     * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.Settings&gt; settingsByModule = 2;</code>
-     */
-
-    public java.util.Map<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings> getSettingsByModule() {
-      return internalGetSettingsByModule().getMap();
-    }
-
-    public static final int FILEDATABYMODULEANDPATCH_FIELD_NUMBER = 3;
-    private static final class FileDataByModuleAndPatchDefaultEntryHolder {
-      static final com.google.protobuf.MapEntry<
-          java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath> defaultEntry =
-              com.google.protobuf.MapEntry
-              .<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath>newDefaultInstance(
-                  org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByModuleAndPatchEntry_descriptor, 
-                  com.google.protobuf.WireFormat.FieldType.STRING,
-                  "",
-                  com.google.protobuf.WireFormat.FieldType.MESSAGE,
-                  org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath.getDefaultInstance());
-    }
-    private com.google.protobuf.MapField<
-        java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath> fileDataByModuleAndPatch_;
-    private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath>
-    internalGetFileDataByModuleAndPatch() {
-      if (fileDataByModuleAndPatch_ == null) {
-        return com.google.protobuf.MapField.emptyMapField(
-            FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry);
-     }
-      return fileDataByModuleAndPatch_;
-    }
-    /**
-     * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileDataByPath&gt; fileDataByModuleAndPatch = 3;</code>
-     */
-
-    public java.util.Map<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath> getFileDataByModuleAndPatch() {
-      return internalGetFileDataByModuleAndPatch().getMap();
-    }
-
-    public static final int LASTANALYSISDATE_FIELD_NUMBER = 4;
-    private long lastAnalysisDate_;
-    /**
-     * <code>optional int64 lastAnalysisDate = 4;</code>
-     */
-    public boolean hasLastAnalysisDate() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
-    }
-    /**
-     * <code>optional int64 lastAnalysisDate = 4;</code>
-     */
-    public long getLastAnalysisDate() {
-      return lastAnalysisDate_;
-    }
-
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized == 1) return true;
-      if (isInitialized == 0) return false;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        output.writeInt64(1, timestamp_);
-      }
-      for (java.util.Map.Entry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings> entry
-           : internalGetSettingsByModule().getMap().entrySet()) {
-        com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings>
-        settingsByModule = SettingsByModuleDefaultEntryHolder.defaultEntry.newBuilderForType()
-            .setKey(entry.getKey())
-            .setValue(entry.getValue())
-            .build();
-        output.writeMessage(2, settingsByModule);
-      }
-      for (java.util.Map.Entry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath> entry
-           : internalGetFileDataByModuleAndPatch().getMap().entrySet()) {
-        com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath>
-        fileDataByModuleAndPatch = FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry.newBuilderForType()
-            .setKey(entry.getKey())
-            .setValue(entry.getValue())
-            .build();
-        output.writeMessage(3, fileDataByModuleAndPatch);
-      }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
-        output.writeInt64(4, lastAnalysisDate_);
-      }
-      unknownFields.writeTo(output);
-    }
-
-    private int memoizedSerializedSize = -1;
-    public int getSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeInt64Size(1, timestamp_);
-      }
-      for (java.util.Map.Entry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings> entry
-           : internalGetSettingsByModule().getMap().entrySet()) {
-        com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings>
-        settingsByModule = SettingsByModuleDefaultEntryHolder.defaultEntry.newBuilderForType()
-            .setKey(entry.getKey())
-            .setValue(entry.getValue())
-            .build();
-        size += com.google.protobuf.CodedOutputStream
-            .computeMessageSize(2, settingsByModule);
-      }
-      for (java.util.Map.Entry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath> entry
-           : internalGetFileDataByModuleAndPatch().getMap().entrySet()) {
-        com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath>
-        fileDataByModuleAndPatch = FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry.newBuilderForType()
-            .setKey(entry.getKey())
-            .setValue(entry.getValue())
-            .build();
-        size += com.google.protobuf.CodedOutputStream
-            .computeMessageSize(3, fileDataByModuleAndPatch);
-      }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeInt64Size(4, lastAnalysisDate_);
-      }
-      size += unknownFields.getSerializedSize();
-      memoizedSerializedSize = size;
-      return size;
-    }
-
-    private static final long serialVersionUID = 0L;
-    public static org.sonarqube.ws.WsBatch.WsProjectResponse parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.sonarqube.ws.WsBatch.WsProjectResponse parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.sonarqube.ws.WsBatch.WsProjectResponse parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static org.sonarqube.ws.WsBatch.WsProjectResponse parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static org.sonarqube.ws.WsBatch.WsProjectResponse parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.sonarqube.ws.WsBatch.WsProjectResponse parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-    public static org.sonarqube.ws.WsBatch.WsProjectResponse parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
-    }
-    public static org.sonarqube.ws.WsBatch.WsProjectResponse parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
-    }
-    public static org.sonarqube.ws.WsBatch.WsProjectResponse parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input);
-    }
-    public static org.sonarqube.ws.WsBatch.WsProjectResponse parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
-    }
-
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder() {
-      return DEFAULT_INSTANCE.toBuilder();
-    }
-    public static Builder newBuilder(org.sonarqube.ws.WsBatch.WsProjectResponse prototype) {
-      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() {
-      return this == DEFAULT_INSTANCE
-          ? new Builder() : new Builder().mergeFrom(this);
-    }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse}
-     *
-     * <pre>
-     * WS api/batch/project
-     * </pre>
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:sonarqube.ws.batch.WsProjectResponse)
-        org.sonarqube.ws.WsBatch.WsProjectResponseOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor;
-      }
-
-      @SuppressWarnings({"rawtypes"})
-      protected com.google.protobuf.MapField internalGetMapField(
-          int number) {
-        switch (number) {
-          case 2:
-            return internalGetSettingsByModule();
-          case 3:
-            return internalGetFileDataByModuleAndPatch();
-          default:
-            throw new RuntimeException(
-                "Invalid map field number: " + number);
-        }
-      }
-      @SuppressWarnings({"rawtypes"})
-      protected com.google.protobuf.MapField internalGetMutableMapField(
-          int number) {
-        switch (number) {
-          case 2:
-            return internalGetMutableSettingsByModule();
-          case 3:
-            return internalGetMutableFileDataByModuleAndPatch();
-          default:
-            throw new RuntimeException(
-                "Invalid map field number: " + number);
-        }
-      }
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.sonarqube.ws.WsBatch.WsProjectResponse.class, org.sonarqube.ws.WsBatch.WsProjectResponse.Builder.class);
-      }
-
-      // Construct using org.sonarqube.ws.WsBatch.WsProjectResponse.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-        }
-      }
-      public Builder clear() {
-        super.clear();
-        timestamp_ = 0L;
-        bitField0_ = (bitField0_ & ~0x00000001);
-        internalGetMutableSettingsByModule().clear();
-        internalGetMutableFileDataByModuleAndPatch().clear();
-        lastAnalysisDate_ = 0L;
-        bitField0_ = (bitField0_ & ~0x00000008);
-        return this;
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return org.sonarqube.ws.WsBatch.internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor;
-      }
-
-      public org.sonarqube.ws.WsBatch.WsProjectResponse getDefaultInstanceForType() {
-        return org.sonarqube.ws.WsBatch.WsProjectResponse.getDefaultInstance();
-      }
-
-      public org.sonarqube.ws.WsBatch.WsProjectResponse build() {
-        org.sonarqube.ws.WsBatch.WsProjectResponse result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public org.sonarqube.ws.WsBatch.WsProjectResponse buildPartial() {
-        org.sonarqube.ws.WsBatch.WsProjectResponse result = new org.sonarqube.ws.WsBatch.WsProjectResponse(this);
-        int from_bitField0_ = bitField0_;
-        int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
-        result.timestamp_ = timestamp_;
-        result.settingsByModule_ = internalGetSettingsByModule();
-        result.settingsByModule_.makeImmutable();
-        result.fileDataByModuleAndPatch_ = internalGetFileDataByModuleAndPatch();
-        result.fileDataByModuleAndPatch_.makeImmutable();
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
-          to_bitField0_ |= 0x00000002;
-        }
-        result.lastAnalysisDate_ = lastAnalysisDate_;
-        result.bitField0_ = to_bitField0_;
-        onBuilt();
-        return result;
-      }
-
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof org.sonarqube.ws.WsBatch.WsProjectResponse) {
-          return mergeFrom((org.sonarqube.ws.WsBatch.WsProjectResponse)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(org.sonarqube.ws.WsBatch.WsProjectResponse other) {
-        if (other == org.sonarqube.ws.WsBatch.WsProjectResponse.getDefaultInstance()) return this;
-        if (other.hasTimestamp()) {
-          setTimestamp(other.getTimestamp());
-        }
-        internalGetMutableSettingsByModule().mergeFrom(
-            other.internalGetSettingsByModule());
-        internalGetMutableFileDataByModuleAndPatch().mergeFrom(
-            other.internalGetFileDataByModuleAndPatch());
-        if (other.hasLastAnalysisDate()) {
-          setLastAnalysisDate(other.getLastAnalysisDate());
-        }
-        this.mergeUnknownFields(other.unknownFields);
-        onChanged();
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        org.sonarqube.ws.WsBatch.WsProjectResponse parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (org.sonarqube.ws.WsBatch.WsProjectResponse) e.getUnfinishedMessage();
-          throw e;
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-      private int bitField0_;
-
-      private long timestamp_ ;
-      /**
-       * <code>optional int64 timestamp = 1;</code>
-       */
-      public boolean hasTimestamp() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>optional int64 timestamp = 1;</code>
-       */
-      public long getTimestamp() {
-        return timestamp_;
-      }
-      /**
-       * <code>optional int64 timestamp = 1;</code>
-       */
-      public Builder setTimestamp(long value) {
-        bitField0_ |= 0x00000001;
-        timestamp_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional int64 timestamp = 1;</code>
-       */
-      public Builder clearTimestamp() {
-        bitField0_ = (bitField0_ & ~0x00000001);
-        timestamp_ = 0L;
-        onChanged();
-        return this;
-      }
-
-      private com.google.protobuf.MapField<
-          java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings> settingsByModule_;
-      private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings>
-      internalGetSettingsByModule() {
-        if (settingsByModule_ == null) {
-          return com.google.protobuf.MapField.emptyMapField(
-              SettingsByModuleDefaultEntryHolder.defaultEntry);
-       }
-        return settingsByModule_;
-      }
-      private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings>
-      internalGetMutableSettingsByModule() {
-        onChanged();;
-        if (settingsByModule_ == null) {
-          settingsByModule_ = com.google.protobuf.MapField.newMapField(
-              SettingsByModuleDefaultEntryHolder.defaultEntry);
-        }
-        if (!settingsByModule_.isMutable()) {
-          settingsByModule_ = settingsByModule_.copy();
-        }
-        return settingsByModule_;
-      }
-      /**
-       * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.Settings&gt; settingsByModule = 2;</code>
-       */
-      public java.util.Map<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings> getSettingsByModule() {
-        return internalGetSettingsByModule().getMap();
-      }
-      /**
-       * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.Settings&gt; settingsByModule = 2;</code>
-       */
-      public java.util.Map<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.Settings>
-      getMutableSettingsByModule() {
-        return internalGetMutableSettingsByModule().getMutableMap();
-      }
-
-      private com.google.protobuf.MapField<
-          java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath> fileDataByModuleAndPatch_;
-      private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath>
-      internalGetFileDataByModuleAndPatch() {
-        if (fileDataByModuleAndPatch_ == null) {
-          return com.google.protobuf.MapField.emptyMapField(
-              FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry);
-       }
-        return fileDataByModuleAndPatch_;
-      }
-      private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath>
-      internalGetMutableFileDataByModuleAndPatch() {
-        onChanged();;
-        if (fileDataByModuleAndPatch_ == null) {
-          fileDataByModuleAndPatch_ = com.google.protobuf.MapField.newMapField(
-              FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry);
-        }
-        if (!fileDataByModuleAndPatch_.isMutable()) {
-          fileDataByModuleAndPatch_ = fileDataByModuleAndPatch_.copy();
-        }
-        return fileDataByModuleAndPatch_;
-      }
-      /**
-       * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileDataByPath&gt; fileDataByModuleAndPatch = 3;</code>
-       */
-      public java.util.Map<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath> getFileDataByModuleAndPatch() {
-        return internalGetFileDataByModuleAndPatch().getMap();
-      }
-      /**
-       * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileDataByPath&gt; fileDataByModuleAndPatch = 3;</code>
-       */
-      public java.util.Map<java.lang.String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath>
-      getMutableFileDataByModuleAndPatch() {
-        return internalGetMutableFileDataByModuleAndPatch().getMutableMap();
-      }
-
-      private long lastAnalysisDate_ ;
-      /**
-       * <code>optional int64 lastAnalysisDate = 4;</code>
-       */
-      public boolean hasLastAnalysisDate() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
-      }
-      /**
-       * <code>optional int64 lastAnalysisDate = 4;</code>
-       */
-      public long getLastAnalysisDate() {
-        return lastAnalysisDate_;
-      }
-      /**
-       * <code>optional int64 lastAnalysisDate = 4;</code>
-       */
-      public Builder setLastAnalysisDate(long value) {
-        bitField0_ |= 0x00000008;
-        lastAnalysisDate_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional int64 lastAnalysisDate = 4;</code>
-       */
-      public Builder clearLastAnalysisDate() {
-        bitField0_ = (bitField0_ & ~0x00000008);
-        lastAnalysisDate_ = 0L;
-        onChanged();
-        return this;
-      }
-
-      // @@protoc_insertion_point(builder_scope:sonarqube.ws.batch.WsProjectResponse)
-    }
-
-    // @@protoc_insertion_point(class_scope:sonarqube.ws.batch.WsProjectResponse)
-    private static final org.sonarqube.ws.WsBatch.WsProjectResponse DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new org.sonarqube.ws.WsBatch.WsProjectResponse();
-    }
-
-    public static org.sonarqube.ws.WsBatch.WsProjectResponse getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    public static final com.google.protobuf.Parser<WsProjectResponse> PARSER =
-        new com.google.protobuf.AbstractParser<WsProjectResponse>() {
-      public WsProjectResponse parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        try {
-          return new WsProjectResponse(input, extensionRegistry);
-        } catch (RuntimeException e) {
-          if (e.getCause() instanceof
-              com.google.protobuf.InvalidProtocolBufferException) {
-            throw (com.google.protobuf.InvalidProtocolBufferException)
-                e.getCause();
-          }
-          throw e;
-        }
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<WsProjectResponse> getParserForType() {
-      return PARSER;
-    }
-
-    public org.sonarqube.ws.WsBatch.WsProjectResponse getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_sonarqube_ws_batch_WsProjectResponse_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_sonarqube_ws_batch_WsProjectResponse_SettingsByModuleEntry_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_sonarqube_ws_batch_WsProjectResponse_SettingsByModuleEntry_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByModuleAndPatchEntry_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByModuleAndPatchEntry_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_SettingsEntry_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_SettingsEntry_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_FileDataByPathEntry_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_FileDataByPathEntry_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_fieldAccessorTable;
-
-  public static com.google.protobuf.Descriptors.FileDescriptor
-      getDescriptor() {
-    return descriptor;
-  }
-  private static com.google.protobuf.Descriptors.FileDescriptor
-      descriptor;
-  static {
-    java.lang.String[] descriptorData = {
-      "\n\016ws-batch.proto\022\022sonarqube.ws.batch\"\364\006\n" +
-      "\021WsProjectResponse\022\021\n\ttimestamp\030\001 \001(\003\022U\n" +
-      "\020settingsByModule\030\002 \003(\0132;.sonarqube.ws.b" +
-      "atch.WsProjectResponse.SettingsByModuleE" +
-      "ntry\022e\n\030fileDataByModuleAndPatch\030\003 \003(\0132C" +
-      ".sonarqube.ws.batch.WsProjectResponse.Fi" +
-      "leDataByModuleAndPatchEntry\022\030\n\020lastAnaly" +
-      "sisDate\030\004 \001(\003\032g\n\025SettingsByModuleEntry\022\013" +
-      "\n\003key\030\001 \001(\t\022=\n\005value\030\002 \001(\0132..sonarqube.w" +
-      "s.batch.WsProjectResponse.Settings:\0028\001\032u",
-      "\n\035FileDataByModuleAndPatchEntry\022\013\n\003key\030\001" +
-      " \001(\t\022C\n\005value\030\002 \001(\01324.sonarqube.ws.batch" +
-      ".WsProjectResponse.FileDataByPath:\0028\001\032\213\001" +
-      "\n\010Settings\022N\n\010settings\030\001 \003(\0132<.sonarqube" +
-      ".ws.batch.WsProjectResponse.Settings.Set" +
-      "tingsEntry\032/\n\rSettingsEntry\022\013\n\003key\030\001 \001(\t" +
-      "\022\r\n\005value\030\002 \001(\t:\0028\001\032\331\001\n\016FileDataByPath\022`" +
-      "\n\016FileDataByPath\030\001 \003(\0132H.sonarqube.ws.ba" +
-      "tch.WsProjectResponse.FileDataByPath.Fil" +
-      "eDataByPathEntry\032e\n\023FileDataByPathEntry\022",
-      "\013\n\003key\030\001 \001(\t\022=\n\005value\030\002 \001(\0132..sonarqube." +
-      "ws.batch.WsProjectResponse.FileData:\0028\001\032" +
-      "*\n\010FileData\022\014\n\004hash\030\001 \001(\t\022\020\n\010revision\030\002 " +
-      "\001(\tB\035\n\020org.sonarqube.wsB\007WsBatchH\001"
-    };
-    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
-        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
-          public com.google.protobuf.ExtensionRegistry assignDescriptors(
-              com.google.protobuf.Descriptors.FileDescriptor root) {
-            descriptor = root;
-            return null;
-          }
-        };
-    com.google.protobuf.Descriptors.FileDescriptor
-      .internalBuildGeneratedFileFrom(descriptorData,
-        new com.google.protobuf.Descriptors.FileDescriptor[] {
-        }, assigner);
-    internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor =
-      getDescriptor().getMessageTypes().get(0);
-    internal_static_sonarqube_ws_batch_WsProjectResponse_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-        internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor,
-        new java.lang.String[] { "Timestamp", "SettingsByModule", "FileDataByModuleAndPatch", "LastAnalysisDate", });
-    internal_static_sonarqube_ws_batch_WsProjectResponse_SettingsByModuleEntry_descriptor =
-      internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor.getNestedTypes().get(0);
-    internal_static_sonarqube_ws_batch_WsProjectResponse_SettingsByModuleEntry_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-        internal_static_sonarqube_ws_batch_WsProjectResponse_SettingsByModuleEntry_descriptor,
-        new java.lang.String[] { "Key", "Value", });
-    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByModuleAndPatchEntry_descriptor =
-      internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor.getNestedTypes().get(1);
-    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByModuleAndPatchEntry_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-        internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByModuleAndPatchEntry_descriptor,
-        new java.lang.String[] { "Key", "Value", });
-    internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor =
-      internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor.getNestedTypes().get(2);
-    internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-        internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor,
-        new java.lang.String[] { "Settings", });
-    internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_SettingsEntry_descriptor =
-      internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor.getNestedTypes().get(0);
-    internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_SettingsEntry_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-        internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_SettingsEntry_descriptor,
-        new java.lang.String[] { "Key", "Value", });
-    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor =
-      internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor.getNestedTypes().get(3);
-    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-        internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor,
-        new java.lang.String[] { "FileDataByPath", });
-    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_FileDataByPathEntry_descriptor =
-      internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor.getNestedTypes().get(0);
-    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_FileDataByPathEntry_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-        internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_FileDataByPathEntry_descriptor,
-        new java.lang.String[] { "Key", "Value", });
-    internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_descriptor =
-      internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor.getNestedTypes().get(4);
-    internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
-        internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_descriptor,
-        new java.lang.String[] { "Hash", "Revision", });
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/sonar-ws/src/main/gen-java/org/sonarqube/ws/WsScanner.java b/sonar-ws/src/main/gen-java/org/sonarqube/ws/WsScanner.java
new file mode 100644 (file)
index 0000000..4432855
--- /dev/null
@@ -0,0 +1,2417 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: ws-scanner.proto
+
+package org.sonarqube.ws;
+
+public final class WsScanner {
+  private WsScanner() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface WsProjectResponseOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:sonarqube.ws.batch.WsProjectResponse)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>optional int64 timestamp = 1;</code>
+     */
+    boolean hasTimestamp();
+    /**
+     * <code>optional int64 timestamp = 1;</code>
+     */
+    long getTimestamp();
+
+    /**
+     * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.Settings&gt; settingsByModule = 2;</code>
+     */
+    java.util.Map<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings>
+    getSettingsByModule();
+
+    /**
+     * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileDataByPath&gt; fileDataByModuleAndPatch = 3;</code>
+     */
+    java.util.Map<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath>
+    getFileDataByModuleAndPatch();
+
+    /**
+     * <code>optional int64 lastAnalysisDate = 4;</code>
+     */
+    boolean hasLastAnalysisDate();
+    /**
+     * <code>optional int64 lastAnalysisDate = 4;</code>
+     */
+    long getLastAnalysisDate();
+  }
+  /**
+   * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse}
+   *
+   * <pre>
+   * WS api/scanner/project
+   * </pre>
+   */
+  public  static final class WsProjectResponse extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:sonarqube.ws.batch.WsProjectResponse)
+      WsProjectResponseOrBuilder {
+    // Use WsProjectResponse.newBuilder() to construct.
+    private WsProjectResponse(com.google.protobuf.GeneratedMessage.Builder builder) {
+      super(builder);
+    }
+    private WsProjectResponse() {
+      timestamp_ = 0L;
+      lastAnalysisDate_ = 0L;
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private WsProjectResponse(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry) {
+      this();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              bitField0_ |= 0x00000001;
+              timestamp_ = input.readInt64();
+              break;
+            }
+            case 18: {
+              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
+                settingsByModule_ = com.google.protobuf.MapField.newMapField(
+                    SettingsByModuleDefaultEntryHolder.defaultEntry);
+                mutable_bitField0_ |= 0x00000002;
+              }
+              com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings>
+              settingsByModule = input.readMessage(
+                  SettingsByModuleDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
+              settingsByModule_.getMutableMap().put(settingsByModule.getKey(), settingsByModule.getValue());
+              break;
+            }
+            case 26: {
+              if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+                fileDataByModuleAndPatch_ = com.google.protobuf.MapField.newMapField(
+                    FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry);
+                mutable_bitField0_ |= 0x00000004;
+              }
+              com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath>
+              fileDataByModuleAndPatch = input.readMessage(
+                  FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
+              fileDataByModuleAndPatch_.getMutableMap().put(fileDataByModuleAndPatch.getKey(), fileDataByModuleAndPatch.getValue());
+              break;
+            }
+            case 32: {
+              bitField0_ |= 0x00000002;
+              lastAnalysisDate_ = input.readInt64();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw new RuntimeException(e.setUnfinishedMessage(this));
+      } catch (java.io.IOException e) {
+        throw new RuntimeException(
+            new com.google.protobuf.InvalidProtocolBufferException(
+                e.getMessage()).setUnfinishedMessage(this));
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor;
+    }
+
+    @SuppressWarnings({"rawtypes"})
+    protected com.google.protobuf.MapField internalGetMapField(
+        int number) {
+      switch (number) {
+        case 2:
+          return internalGetSettingsByModule();
+        case 3:
+          return internalGetFileDataByModuleAndPatch();
+        default:
+          throw new RuntimeException(
+              "Invalid map field number: " + number);
+      }
+    }
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.sonarqube.ws.WsScanner.WsProjectResponse.class, org.sonarqube.ws.WsScanner.WsProjectResponse.Builder.class);
+    }
+
+    public interface SettingsOrBuilder extends
+        // @@protoc_insertion_point(interface_extends:sonarqube.ws.batch.WsProjectResponse.Settings)
+        com.google.protobuf.MessageOrBuilder {
+
+      /**
+       * <code>map&lt;string, string&gt; settings = 1;</code>
+       */
+      java.util.Map<java.lang.String, java.lang.String>
+      getSettings();
+    }
+    /**
+     * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse.Settings}
+     */
+    public  static final class Settings extends
+        com.google.protobuf.GeneratedMessage implements
+        // @@protoc_insertion_point(message_implements:sonarqube.ws.batch.WsProjectResponse.Settings)
+        SettingsOrBuilder {
+      // Use Settings.newBuilder() to construct.
+      private Settings(com.google.protobuf.GeneratedMessage.Builder builder) {
+        super(builder);
+      }
+      private Settings() {
+      }
+
+      @java.lang.Override
+      public final com.google.protobuf.UnknownFieldSet
+      getUnknownFields() {
+        return this.unknownFields;
+      }
+      private Settings(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry) {
+        this();
+        int mutable_bitField0_ = 0;
+        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+            com.google.protobuf.UnknownFieldSet.newBuilder();
+        try {
+          boolean done = false;
+          while (!done) {
+            int tag = input.readTag();
+            switch (tag) {
+              case 0:
+                done = true;
+                break;
+              default: {
+                if (!parseUnknownField(input, unknownFields,
+                                       extensionRegistry, tag)) {
+                  done = true;
+                }
+                break;
+              }
+              case 10: {
+                if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                  settings_ = com.google.protobuf.MapField.newMapField(
+                      SettingsDefaultEntryHolder.defaultEntry);
+                  mutable_bitField0_ |= 0x00000001;
+                }
+                com.google.protobuf.MapEntry<java.lang.String, java.lang.String>
+                settings = input.readMessage(
+                    SettingsDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
+                settings_.getMutableMap().put(settings.getKey(), settings.getValue());
+                break;
+              }
+            }
+          }
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          throw new RuntimeException(e.setUnfinishedMessage(this));
+        } catch (java.io.IOException e) {
+          throw new RuntimeException(
+              new com.google.protobuf.InvalidProtocolBufferException(
+                  e.getMessage()).setUnfinishedMessage(this));
+        } finally {
+          this.unknownFields = unknownFields.build();
+          makeExtensionsImmutable();
+        }
+      }
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor;
+      }
+
+      @SuppressWarnings({"rawtypes"})
+      protected com.google.protobuf.MapField internalGetMapField(
+          int number) {
+        switch (number) {
+          case 1:
+            return internalGetSettings();
+          default:
+            throw new RuntimeException(
+                "Invalid map field number: " + number);
+        }
+      }
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.sonarqube.ws.WsScanner.WsProjectResponse.Settings.class, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings.Builder.class);
+      }
+
+      public static final int SETTINGS_FIELD_NUMBER = 1;
+      private static final class SettingsDefaultEntryHolder {
+        static final com.google.protobuf.MapEntry<
+            java.lang.String, java.lang.String> defaultEntry =
+                com.google.protobuf.MapEntry
+                .<java.lang.String, java.lang.String>newDefaultInstance(
+                    org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_SettingsEntry_descriptor, 
+                    com.google.protobuf.WireFormat.FieldType.STRING,
+                    "",
+                    com.google.protobuf.WireFormat.FieldType.STRING,
+                    "");
+      }
+      private com.google.protobuf.MapField<
+          java.lang.String, java.lang.String> settings_;
+      private com.google.protobuf.MapField<java.lang.String, java.lang.String>
+      internalGetSettings() {
+        if (settings_ == null) {
+          return com.google.protobuf.MapField.emptyMapField(
+              SettingsDefaultEntryHolder.defaultEntry);
+       }
+        return settings_;
+      }
+      /**
+       * <code>map&lt;string, string&gt; settings = 1;</code>
+       */
+
+      public java.util.Map<java.lang.String, java.lang.String> getSettings() {
+        return internalGetSettings().getMap();
+      }
+
+      private byte memoizedIsInitialized = -1;
+      public final boolean isInitialized() {
+        byte isInitialized = memoizedIsInitialized;
+        if (isInitialized == 1) return true;
+        if (isInitialized == 0) return false;
+
+        memoizedIsInitialized = 1;
+        return true;
+      }
+
+      public void writeTo(com.google.protobuf.CodedOutputStream output)
+                          throws java.io.IOException {
+        for (java.util.Map.Entry<java.lang.String, java.lang.String> entry
+             : internalGetSettings().getMap().entrySet()) {
+          com.google.protobuf.MapEntry<java.lang.String, java.lang.String>
+          settings = SettingsDefaultEntryHolder.defaultEntry.newBuilderForType()
+              .setKey(entry.getKey())
+              .setValue(entry.getValue())
+              .build();
+          output.writeMessage(1, settings);
+        }
+        unknownFields.writeTo(output);
+      }
+
+      private int memoizedSerializedSize = -1;
+      public int getSerializedSize() {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+
+        size = 0;
+        for (java.util.Map.Entry<java.lang.String, java.lang.String> entry
+             : internalGetSettings().getMap().entrySet()) {
+          com.google.protobuf.MapEntry<java.lang.String, java.lang.String>
+          settings = SettingsDefaultEntryHolder.defaultEntry.newBuilderForType()
+              .setKey(entry.getKey())
+              .setValue(entry.getValue())
+              .build();
+          size += com.google.protobuf.CodedOutputStream
+              .computeMessageSize(1, settings);
+        }
+        size += unknownFields.getSerializedSize();
+        memoizedSerializedSize = size;
+        return size;
+      }
+
+      private static final long serialVersionUID = 0L;
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.Settings parseFrom(
+          com.google.protobuf.ByteString data)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.Settings parseFrom(
+          com.google.protobuf.ByteString data,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data, extensionRegistry);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.Settings parseFrom(byte[] data)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.Settings parseFrom(
+          byte[] data,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data, extensionRegistry);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.Settings parseFrom(java.io.InputStream input)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.Settings parseFrom(
+          java.io.InputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input, extensionRegistry);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.Settings parseDelimitedFrom(java.io.InputStream input)
+          throws java.io.IOException {
+        return PARSER.parseDelimitedFrom(input);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.Settings parseDelimitedFrom(
+          java.io.InputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.Settings parseFrom(
+          com.google.protobuf.CodedInputStream input)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.Settings parseFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input, extensionRegistry);
+      }
+
+      public Builder newBuilderForType() { return newBuilder(); }
+      public static Builder newBuilder() {
+        return DEFAULT_INSTANCE.toBuilder();
+      }
+      public static Builder newBuilder(org.sonarqube.ws.WsScanner.WsProjectResponse.Settings prototype) {
+        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+      }
+      public Builder toBuilder() {
+        return this == DEFAULT_INSTANCE
+            ? new Builder() : new Builder().mergeFrom(this);
+      }
+
+      @java.lang.Override
+      protected Builder newBuilderForType(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        Builder builder = new Builder(parent);
+        return builder;
+      }
+      /**
+       * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse.Settings}
+       */
+      public static final class Builder extends
+          com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+          // @@protoc_insertion_point(builder_implements:sonarqube.ws.batch.WsProjectResponse.Settings)
+          org.sonarqube.ws.WsScanner.WsProjectResponse.SettingsOrBuilder {
+        public static final com.google.protobuf.Descriptors.Descriptor
+            getDescriptor() {
+          return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor;
+        }
+
+        @SuppressWarnings({"rawtypes"})
+        protected com.google.protobuf.MapField internalGetMapField(
+            int number) {
+          switch (number) {
+            case 1:
+              return internalGetSettings();
+            default:
+              throw new RuntimeException(
+                  "Invalid map field number: " + number);
+          }
+        }
+        @SuppressWarnings({"rawtypes"})
+        protected com.google.protobuf.MapField internalGetMutableMapField(
+            int number) {
+          switch (number) {
+            case 1:
+              return internalGetMutableSettings();
+            default:
+              throw new RuntimeException(
+                  "Invalid map field number: " + number);
+          }
+        }
+        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+            internalGetFieldAccessorTable() {
+          return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_fieldAccessorTable
+              .ensureFieldAccessorsInitialized(
+                  org.sonarqube.ws.WsScanner.WsProjectResponse.Settings.class, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings.Builder.class);
+        }
+
+        // Construct using org.sonarqube.ws.WsScanner.WsProjectResponse.Settings.newBuilder()
+        private Builder() {
+          maybeForceBuilderInitialization();
+        }
+
+        private Builder(
+            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          super(parent);
+          maybeForceBuilderInitialization();
+        }
+        private void maybeForceBuilderInitialization() {
+          if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          }
+        }
+        public Builder clear() {
+          super.clear();
+          internalGetMutableSettings().clear();
+          return this;
+        }
+
+        public com.google.protobuf.Descriptors.Descriptor
+            getDescriptorForType() {
+          return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor;
+        }
+
+        public org.sonarqube.ws.WsScanner.WsProjectResponse.Settings getDefaultInstanceForType() {
+          return org.sonarqube.ws.WsScanner.WsProjectResponse.Settings.getDefaultInstance();
+        }
+
+        public org.sonarqube.ws.WsScanner.WsProjectResponse.Settings build() {
+          org.sonarqube.ws.WsScanner.WsProjectResponse.Settings result = buildPartial();
+          if (!result.isInitialized()) {
+            throw newUninitializedMessageException(result);
+          }
+          return result;
+        }
+
+        public org.sonarqube.ws.WsScanner.WsProjectResponse.Settings buildPartial() {
+          org.sonarqube.ws.WsScanner.WsProjectResponse.Settings result = new org.sonarqube.ws.WsScanner.WsProjectResponse.Settings(this);
+          int from_bitField0_ = bitField0_;
+          result.settings_ = internalGetSettings();
+          result.settings_.makeImmutable();
+          onBuilt();
+          return result;
+        }
+
+        public Builder mergeFrom(com.google.protobuf.Message other) {
+          if (other instanceof org.sonarqube.ws.WsScanner.WsProjectResponse.Settings) {
+            return mergeFrom((org.sonarqube.ws.WsScanner.WsProjectResponse.Settings)other);
+          } else {
+            super.mergeFrom(other);
+            return this;
+          }
+        }
+
+        public Builder mergeFrom(org.sonarqube.ws.WsScanner.WsProjectResponse.Settings other) {
+          if (other == org.sonarqube.ws.WsScanner.WsProjectResponse.Settings.getDefaultInstance()) return this;
+          internalGetMutableSettings().mergeFrom(
+              other.internalGetSettings());
+          this.mergeUnknownFields(other.unknownFields);
+          onChanged();
+          return this;
+        }
+
+        public final boolean isInitialized() {
+          return true;
+        }
+
+        public Builder mergeFrom(
+            com.google.protobuf.CodedInputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws java.io.IOException {
+          org.sonarqube.ws.WsScanner.WsProjectResponse.Settings parsedMessage = null;
+          try {
+            parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+            parsedMessage = (org.sonarqube.ws.WsScanner.WsProjectResponse.Settings) e.getUnfinishedMessage();
+            throw e;
+          } finally {
+            if (parsedMessage != null) {
+              mergeFrom(parsedMessage);
+            }
+          }
+          return this;
+        }
+        private int bitField0_;
+
+        private com.google.protobuf.MapField<
+            java.lang.String, java.lang.String> settings_;
+        private com.google.protobuf.MapField<java.lang.String, java.lang.String>
+        internalGetSettings() {
+          if (settings_ == null) {
+            return com.google.protobuf.MapField.emptyMapField(
+                SettingsDefaultEntryHolder.defaultEntry);
+         }
+          return settings_;
+        }
+        private com.google.protobuf.MapField<java.lang.String, java.lang.String>
+        internalGetMutableSettings() {
+          onChanged();;
+          if (settings_ == null) {
+            settings_ = com.google.protobuf.MapField.newMapField(
+                SettingsDefaultEntryHolder.defaultEntry);
+          }
+          if (!settings_.isMutable()) {
+            settings_ = settings_.copy();
+          }
+          return settings_;
+        }
+        /**
+         * <code>map&lt;string, string&gt; settings = 1;</code>
+         */
+        public java.util.Map<java.lang.String, java.lang.String> getSettings() {
+          return internalGetSettings().getMap();
+        }
+        /**
+         * <code>map&lt;string, string&gt; settings = 1;</code>
+         */
+        public java.util.Map<java.lang.String, java.lang.String>
+        getMutableSettings() {
+          return internalGetMutableSettings().getMutableMap();
+        }
+
+        // @@protoc_insertion_point(builder_scope:sonarqube.ws.batch.WsProjectResponse.Settings)
+      }
+
+      // @@protoc_insertion_point(class_scope:sonarqube.ws.batch.WsProjectResponse.Settings)
+      private static final org.sonarqube.ws.WsScanner.WsProjectResponse.Settings DEFAULT_INSTANCE;
+      static {
+        DEFAULT_INSTANCE = new org.sonarqube.ws.WsScanner.WsProjectResponse.Settings();
+      }
+
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.Settings getDefaultInstance() {
+        return DEFAULT_INSTANCE;
+      }
+
+      public static final com.google.protobuf.Parser<Settings> PARSER =
+          new com.google.protobuf.AbstractParser<Settings>() {
+        public Settings parsePartialFrom(
+            com.google.protobuf.CodedInputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws com.google.protobuf.InvalidProtocolBufferException {
+          try {
+            return new Settings(input, extensionRegistry);
+          } catch (RuntimeException e) {
+            if (e.getCause() instanceof
+                com.google.protobuf.InvalidProtocolBufferException) {
+              throw (com.google.protobuf.InvalidProtocolBufferException)
+                  e.getCause();
+            }
+            throw e;
+          }
+        }
+      };
+
+      @java.lang.Override
+      public com.google.protobuf.Parser<Settings> getParserForType() {
+        return PARSER;
+      }
+
+      public org.sonarqube.ws.WsScanner.WsProjectResponse.Settings getDefaultInstanceForType() {
+        return DEFAULT_INSTANCE;
+      }
+
+    }
+
+    public interface FileDataByPathOrBuilder extends
+        // @@protoc_insertion_point(interface_extends:sonarqube.ws.batch.WsProjectResponse.FileDataByPath)
+        com.google.protobuf.MessageOrBuilder {
+
+      /**
+       * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileData&gt; FileDataByPath = 1;</code>
+       */
+      java.util.Map<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData>
+      getFileDataByPath();
+    }
+    /**
+     * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse.FileDataByPath}
+     */
+    public  static final class FileDataByPath extends
+        com.google.protobuf.GeneratedMessage implements
+        // @@protoc_insertion_point(message_implements:sonarqube.ws.batch.WsProjectResponse.FileDataByPath)
+        FileDataByPathOrBuilder {
+      // Use FileDataByPath.newBuilder() to construct.
+      private FileDataByPath(com.google.protobuf.GeneratedMessage.Builder builder) {
+        super(builder);
+      }
+      private FileDataByPath() {
+      }
+
+      @java.lang.Override
+      public final com.google.protobuf.UnknownFieldSet
+      getUnknownFields() {
+        return this.unknownFields;
+      }
+      private FileDataByPath(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry) {
+        this();
+        int mutable_bitField0_ = 0;
+        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+            com.google.protobuf.UnknownFieldSet.newBuilder();
+        try {
+          boolean done = false;
+          while (!done) {
+            int tag = input.readTag();
+            switch (tag) {
+              case 0:
+                done = true;
+                break;
+              default: {
+                if (!parseUnknownField(input, unknownFields,
+                                       extensionRegistry, tag)) {
+                  done = true;
+                }
+                break;
+              }
+              case 10: {
+                if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                  fileDataByPath_ = com.google.protobuf.MapField.newMapField(
+                      FileDataByPathDefaultEntryHolder.defaultEntry);
+                  mutable_bitField0_ |= 0x00000001;
+                }
+                com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData>
+                fileDataByPath = input.readMessage(
+                    FileDataByPathDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
+                fileDataByPath_.getMutableMap().put(fileDataByPath.getKey(), fileDataByPath.getValue());
+                break;
+              }
+            }
+          }
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          throw new RuntimeException(e.setUnfinishedMessage(this));
+        } catch (java.io.IOException e) {
+          throw new RuntimeException(
+              new com.google.protobuf.InvalidProtocolBufferException(
+                  e.getMessage()).setUnfinishedMessage(this));
+        } finally {
+          this.unknownFields = unknownFields.build();
+          makeExtensionsImmutable();
+        }
+      }
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor;
+      }
+
+      @SuppressWarnings({"rawtypes"})
+      protected com.google.protobuf.MapField internalGetMapField(
+          int number) {
+        switch (number) {
+          case 1:
+            return internalGetFileDataByPath();
+          default:
+            throw new RuntimeException(
+                "Invalid map field number: " + number);
+        }
+      }
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath.class, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath.Builder.class);
+      }
+
+      public static final int FILEDATABYPATH_FIELD_NUMBER = 1;
+      private static final class FileDataByPathDefaultEntryHolder {
+        static final com.google.protobuf.MapEntry<
+            java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData> defaultEntry =
+                com.google.protobuf.MapEntry
+                .<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData>newDefaultInstance(
+                    org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_FileDataByPathEntry_descriptor, 
+                    com.google.protobuf.WireFormat.FieldType.STRING,
+                    "",
+                    com.google.protobuf.WireFormat.FieldType.MESSAGE,
+                    org.sonarqube.ws.WsScanner.WsProjectResponse.FileData.getDefaultInstance());
+      }
+      private com.google.protobuf.MapField<
+          java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData> fileDataByPath_;
+      private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData>
+      internalGetFileDataByPath() {
+        if (fileDataByPath_ == null) {
+          return com.google.protobuf.MapField.emptyMapField(
+              FileDataByPathDefaultEntryHolder.defaultEntry);
+       }
+        return fileDataByPath_;
+      }
+      /**
+       * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileData&gt; FileDataByPath = 1;</code>
+       */
+
+      public java.util.Map<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData> getFileDataByPath() {
+        return internalGetFileDataByPath().getMap();
+      }
+
+      private byte memoizedIsInitialized = -1;
+      public final boolean isInitialized() {
+        byte isInitialized = memoizedIsInitialized;
+        if (isInitialized == 1) return true;
+        if (isInitialized == 0) return false;
+
+        memoizedIsInitialized = 1;
+        return true;
+      }
+
+      public void writeTo(com.google.protobuf.CodedOutputStream output)
+                          throws java.io.IOException {
+        for (java.util.Map.Entry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData> entry
+             : internalGetFileDataByPath().getMap().entrySet()) {
+          com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData>
+          fileDataByPath = FileDataByPathDefaultEntryHolder.defaultEntry.newBuilderForType()
+              .setKey(entry.getKey())
+              .setValue(entry.getValue())
+              .build();
+          output.writeMessage(1, fileDataByPath);
+        }
+        unknownFields.writeTo(output);
+      }
+
+      private int memoizedSerializedSize = -1;
+      public int getSerializedSize() {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+
+        size = 0;
+        for (java.util.Map.Entry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData> entry
+             : internalGetFileDataByPath().getMap().entrySet()) {
+          com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData>
+          fileDataByPath = FileDataByPathDefaultEntryHolder.defaultEntry.newBuilderForType()
+              .setKey(entry.getKey())
+              .setValue(entry.getValue())
+              .build();
+          size += com.google.protobuf.CodedOutputStream
+              .computeMessageSize(1, fileDataByPath);
+        }
+        size += unknownFields.getSerializedSize();
+        memoizedSerializedSize = size;
+        return size;
+      }
+
+      private static final long serialVersionUID = 0L;
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath parseFrom(
+          com.google.protobuf.ByteString data)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath parseFrom(
+          com.google.protobuf.ByteString data,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data, extensionRegistry);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath parseFrom(byte[] data)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath parseFrom(
+          byte[] data,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data, extensionRegistry);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath parseFrom(java.io.InputStream input)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath parseFrom(
+          java.io.InputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input, extensionRegistry);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath parseDelimitedFrom(java.io.InputStream input)
+          throws java.io.IOException {
+        return PARSER.parseDelimitedFrom(input);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath parseDelimitedFrom(
+          java.io.InputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath parseFrom(
+          com.google.protobuf.CodedInputStream input)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath parseFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input, extensionRegistry);
+      }
+
+      public Builder newBuilderForType() { return newBuilder(); }
+      public static Builder newBuilder() {
+        return DEFAULT_INSTANCE.toBuilder();
+      }
+      public static Builder newBuilder(org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath prototype) {
+        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+      }
+      public Builder toBuilder() {
+        return this == DEFAULT_INSTANCE
+            ? new Builder() : new Builder().mergeFrom(this);
+      }
+
+      @java.lang.Override
+      protected Builder newBuilderForType(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        Builder builder = new Builder(parent);
+        return builder;
+      }
+      /**
+       * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse.FileDataByPath}
+       */
+      public static final class Builder extends
+          com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+          // @@protoc_insertion_point(builder_implements:sonarqube.ws.batch.WsProjectResponse.FileDataByPath)
+          org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPathOrBuilder {
+        public static final com.google.protobuf.Descriptors.Descriptor
+            getDescriptor() {
+          return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor;
+        }
+
+        @SuppressWarnings({"rawtypes"})
+        protected com.google.protobuf.MapField internalGetMapField(
+            int number) {
+          switch (number) {
+            case 1:
+              return internalGetFileDataByPath();
+            default:
+              throw new RuntimeException(
+                  "Invalid map field number: " + number);
+          }
+        }
+        @SuppressWarnings({"rawtypes"})
+        protected com.google.protobuf.MapField internalGetMutableMapField(
+            int number) {
+          switch (number) {
+            case 1:
+              return internalGetMutableFileDataByPath();
+            default:
+              throw new RuntimeException(
+                  "Invalid map field number: " + number);
+          }
+        }
+        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+            internalGetFieldAccessorTable() {
+          return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_fieldAccessorTable
+              .ensureFieldAccessorsInitialized(
+                  org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath.class, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath.Builder.class);
+        }
+
+        // Construct using org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath.newBuilder()
+        private Builder() {
+          maybeForceBuilderInitialization();
+        }
+
+        private Builder(
+            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          super(parent);
+          maybeForceBuilderInitialization();
+        }
+        private void maybeForceBuilderInitialization() {
+          if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          }
+        }
+        public Builder clear() {
+          super.clear();
+          internalGetMutableFileDataByPath().clear();
+          return this;
+        }
+
+        public com.google.protobuf.Descriptors.Descriptor
+            getDescriptorForType() {
+          return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor;
+        }
+
+        public org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath getDefaultInstanceForType() {
+          return org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath.getDefaultInstance();
+        }
+
+        public org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath build() {
+          org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath result = buildPartial();
+          if (!result.isInitialized()) {
+            throw newUninitializedMessageException(result);
+          }
+          return result;
+        }
+
+        public org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath buildPartial() {
+          org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath result = new org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath(this);
+          int from_bitField0_ = bitField0_;
+          result.fileDataByPath_ = internalGetFileDataByPath();
+          result.fileDataByPath_.makeImmutable();
+          onBuilt();
+          return result;
+        }
+
+        public Builder mergeFrom(com.google.protobuf.Message other) {
+          if (other instanceof org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath) {
+            return mergeFrom((org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath)other);
+          } else {
+            super.mergeFrom(other);
+            return this;
+          }
+        }
+
+        public Builder mergeFrom(org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath other) {
+          if (other == org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath.getDefaultInstance()) return this;
+          internalGetMutableFileDataByPath().mergeFrom(
+              other.internalGetFileDataByPath());
+          this.mergeUnknownFields(other.unknownFields);
+          onChanged();
+          return this;
+        }
+
+        public final boolean isInitialized() {
+          return true;
+        }
+
+        public Builder mergeFrom(
+            com.google.protobuf.CodedInputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws java.io.IOException {
+          org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath parsedMessage = null;
+          try {
+            parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+            parsedMessage = (org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath) e.getUnfinishedMessage();
+            throw e;
+          } finally {
+            if (parsedMessage != null) {
+              mergeFrom(parsedMessage);
+            }
+          }
+          return this;
+        }
+        private int bitField0_;
+
+        private com.google.protobuf.MapField<
+            java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData> fileDataByPath_;
+        private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData>
+        internalGetFileDataByPath() {
+          if (fileDataByPath_ == null) {
+            return com.google.protobuf.MapField.emptyMapField(
+                FileDataByPathDefaultEntryHolder.defaultEntry);
+         }
+          return fileDataByPath_;
+        }
+        private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData>
+        internalGetMutableFileDataByPath() {
+          onChanged();;
+          if (fileDataByPath_ == null) {
+            fileDataByPath_ = com.google.protobuf.MapField.newMapField(
+                FileDataByPathDefaultEntryHolder.defaultEntry);
+          }
+          if (!fileDataByPath_.isMutable()) {
+            fileDataByPath_ = fileDataByPath_.copy();
+          }
+          return fileDataByPath_;
+        }
+        /**
+         * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileData&gt; FileDataByPath = 1;</code>
+         */
+        public java.util.Map<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData> getFileDataByPath() {
+          return internalGetFileDataByPath().getMap();
+        }
+        /**
+         * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileData&gt; FileDataByPath = 1;</code>
+         */
+        public java.util.Map<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData>
+        getMutableFileDataByPath() {
+          return internalGetMutableFileDataByPath().getMutableMap();
+        }
+
+        // @@protoc_insertion_point(builder_scope:sonarqube.ws.batch.WsProjectResponse.FileDataByPath)
+      }
+
+      // @@protoc_insertion_point(class_scope:sonarqube.ws.batch.WsProjectResponse.FileDataByPath)
+      private static final org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath DEFAULT_INSTANCE;
+      static {
+        DEFAULT_INSTANCE = new org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath();
+      }
+
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath getDefaultInstance() {
+        return DEFAULT_INSTANCE;
+      }
+
+      public static final com.google.protobuf.Parser<FileDataByPath> PARSER =
+          new com.google.protobuf.AbstractParser<FileDataByPath>() {
+        public FileDataByPath parsePartialFrom(
+            com.google.protobuf.CodedInputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws com.google.protobuf.InvalidProtocolBufferException {
+          try {
+            return new FileDataByPath(input, extensionRegistry);
+          } catch (RuntimeException e) {
+            if (e.getCause() instanceof
+                com.google.protobuf.InvalidProtocolBufferException) {
+              throw (com.google.protobuf.InvalidProtocolBufferException)
+                  e.getCause();
+            }
+            throw e;
+          }
+        }
+      };
+
+      @java.lang.Override
+      public com.google.protobuf.Parser<FileDataByPath> getParserForType() {
+        return PARSER;
+      }
+
+      public org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath getDefaultInstanceForType() {
+        return DEFAULT_INSTANCE;
+      }
+
+    }
+
+    public interface FileDataOrBuilder extends
+        // @@protoc_insertion_point(interface_extends:sonarqube.ws.batch.WsProjectResponse.FileData)
+        com.google.protobuf.MessageOrBuilder {
+
+      /**
+       * <code>optional string hash = 1;</code>
+       */
+      boolean hasHash();
+      /**
+       * <code>optional string hash = 1;</code>
+       */
+      java.lang.String getHash();
+      /**
+       * <code>optional string hash = 1;</code>
+       */
+      com.google.protobuf.ByteString
+          getHashBytes();
+
+      /**
+       * <code>optional string revision = 2;</code>
+       */
+      boolean hasRevision();
+      /**
+       * <code>optional string revision = 2;</code>
+       */
+      java.lang.String getRevision();
+      /**
+       * <code>optional string revision = 2;</code>
+       */
+      com.google.protobuf.ByteString
+          getRevisionBytes();
+    }
+    /**
+     * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse.FileData}
+     */
+    public  static final class FileData extends
+        com.google.protobuf.GeneratedMessage implements
+        // @@protoc_insertion_point(message_implements:sonarqube.ws.batch.WsProjectResponse.FileData)
+        FileDataOrBuilder {
+      // Use FileData.newBuilder() to construct.
+      private FileData(com.google.protobuf.GeneratedMessage.Builder builder) {
+        super(builder);
+      }
+      private FileData() {
+        hash_ = "";
+        revision_ = "";
+      }
+
+      @java.lang.Override
+      public final com.google.protobuf.UnknownFieldSet
+      getUnknownFields() {
+        return this.unknownFields;
+      }
+      private FileData(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry) {
+        this();
+        int mutable_bitField0_ = 0;
+        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+            com.google.protobuf.UnknownFieldSet.newBuilder();
+        try {
+          boolean done = false;
+          while (!done) {
+            int tag = input.readTag();
+            switch (tag) {
+              case 0:
+                done = true;
+                break;
+              default: {
+                if (!parseUnknownField(input, unknownFields,
+                                       extensionRegistry, tag)) {
+                  done = true;
+                }
+                break;
+              }
+              case 10: {
+                com.google.protobuf.ByteString bs = input.readBytes();
+                bitField0_ |= 0x00000001;
+                hash_ = bs;
+                break;
+              }
+              case 18: {
+                com.google.protobuf.ByteString bs = input.readBytes();
+                bitField0_ |= 0x00000002;
+                revision_ = bs;
+                break;
+              }
+            }
+          }
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          throw new RuntimeException(e.setUnfinishedMessage(this));
+        } catch (java.io.IOException e) {
+          throw new RuntimeException(
+              new com.google.protobuf.InvalidProtocolBufferException(
+                  e.getMessage()).setUnfinishedMessage(this));
+        } finally {
+          this.unknownFields = unknownFields.build();
+          makeExtensionsImmutable();
+        }
+      }
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.sonarqube.ws.WsScanner.WsProjectResponse.FileData.class, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData.Builder.class);
+      }
+
+      private int bitField0_;
+      public static final int HASH_FIELD_NUMBER = 1;
+      private volatile java.lang.Object hash_;
+      /**
+       * <code>optional string hash = 1;</code>
+       */
+      public boolean hasHash() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional string hash = 1;</code>
+       */
+      public java.lang.String getHash() {
+        java.lang.Object ref = hash_;
+        if (ref instanceof java.lang.String) {
+          return (java.lang.String) ref;
+        } else {
+          com.google.protobuf.ByteString bs = 
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (bs.isValidUtf8()) {
+            hash_ = s;
+          }
+          return s;
+        }
+      }
+      /**
+       * <code>optional string hash = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getHashBytes() {
+        java.lang.Object ref = hash_;
+        if (ref instanceof java.lang.String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          hash_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+
+      public static final int REVISION_FIELD_NUMBER = 2;
+      private volatile java.lang.Object revision_;
+      /**
+       * <code>optional string revision = 2;</code>
+       */
+      public boolean hasRevision() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional string revision = 2;</code>
+       */
+      public java.lang.String getRevision() {
+        java.lang.Object ref = revision_;
+        if (ref instanceof java.lang.String) {
+          return (java.lang.String) ref;
+        } else {
+          com.google.protobuf.ByteString bs = 
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (bs.isValidUtf8()) {
+            revision_ = s;
+          }
+          return s;
+        }
+      }
+      /**
+       * <code>optional string revision = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getRevisionBytes() {
+        java.lang.Object ref = revision_;
+        if (ref instanceof java.lang.String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          revision_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+
+      private byte memoizedIsInitialized = -1;
+      public final boolean isInitialized() {
+        byte isInitialized = memoizedIsInitialized;
+        if (isInitialized == 1) return true;
+        if (isInitialized == 0) return false;
+
+        memoizedIsInitialized = 1;
+        return true;
+      }
+
+      public void writeTo(com.google.protobuf.CodedOutputStream output)
+                          throws java.io.IOException {
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          output.writeBytes(1, getHashBytes());
+        }
+        if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          output.writeBytes(2, getRevisionBytes());
+        }
+        unknownFields.writeTo(output);
+      }
+
+      private int memoizedSerializedSize = -1;
+      public int getSerializedSize() {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+
+        size = 0;
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          size += com.google.protobuf.CodedOutputStream
+            .computeBytesSize(1, getHashBytes());
+        }
+        if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          size += com.google.protobuf.CodedOutputStream
+            .computeBytesSize(2, getRevisionBytes());
+        }
+        size += unknownFields.getSerializedSize();
+        memoizedSerializedSize = size;
+        return size;
+      }
+
+      private static final long serialVersionUID = 0L;
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileData parseFrom(
+          com.google.protobuf.ByteString data)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileData parseFrom(
+          com.google.protobuf.ByteString data,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data, extensionRegistry);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileData parseFrom(byte[] data)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileData parseFrom(
+          byte[] data,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data, extensionRegistry);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileData parseFrom(java.io.InputStream input)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileData parseFrom(
+          java.io.InputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input, extensionRegistry);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileData parseDelimitedFrom(java.io.InputStream input)
+          throws java.io.IOException {
+        return PARSER.parseDelimitedFrom(input);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileData parseDelimitedFrom(
+          java.io.InputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileData parseFrom(
+          com.google.protobuf.CodedInputStream input)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input);
+      }
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileData parseFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input, extensionRegistry);
+      }
+
+      public Builder newBuilderForType() { return newBuilder(); }
+      public static Builder newBuilder() {
+        return DEFAULT_INSTANCE.toBuilder();
+      }
+      public static Builder newBuilder(org.sonarqube.ws.WsScanner.WsProjectResponse.FileData prototype) {
+        return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+      }
+      public Builder toBuilder() {
+        return this == DEFAULT_INSTANCE
+            ? new Builder() : new Builder().mergeFrom(this);
+      }
+
+      @java.lang.Override
+      protected Builder newBuilderForType(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        Builder builder = new Builder(parent);
+        return builder;
+      }
+      /**
+       * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse.FileData}
+       */
+      public static final class Builder extends
+          com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+          // @@protoc_insertion_point(builder_implements:sonarqube.ws.batch.WsProjectResponse.FileData)
+          org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataOrBuilder {
+        public static final com.google.protobuf.Descriptors.Descriptor
+            getDescriptor() {
+          return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_descriptor;
+        }
+
+        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+            internalGetFieldAccessorTable() {
+          return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_fieldAccessorTable
+              .ensureFieldAccessorsInitialized(
+                  org.sonarqube.ws.WsScanner.WsProjectResponse.FileData.class, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData.Builder.class);
+        }
+
+        // Construct using org.sonarqube.ws.WsScanner.WsProjectResponse.FileData.newBuilder()
+        private Builder() {
+          maybeForceBuilderInitialization();
+        }
+
+        private Builder(
+            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          super(parent);
+          maybeForceBuilderInitialization();
+        }
+        private void maybeForceBuilderInitialization() {
+          if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          }
+        }
+        public Builder clear() {
+          super.clear();
+          hash_ = "";
+          bitField0_ = (bitField0_ & ~0x00000001);
+          revision_ = "";
+          bitField0_ = (bitField0_ & ~0x00000002);
+          return this;
+        }
+
+        public com.google.protobuf.Descriptors.Descriptor
+            getDescriptorForType() {
+          return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_descriptor;
+        }
+
+        public org.sonarqube.ws.WsScanner.WsProjectResponse.FileData getDefaultInstanceForType() {
+          return org.sonarqube.ws.WsScanner.WsProjectResponse.FileData.getDefaultInstance();
+        }
+
+        public org.sonarqube.ws.WsScanner.WsProjectResponse.FileData build() {
+          org.sonarqube.ws.WsScanner.WsProjectResponse.FileData result = buildPartial();
+          if (!result.isInitialized()) {
+            throw newUninitializedMessageException(result);
+          }
+          return result;
+        }
+
+        public org.sonarqube.ws.WsScanner.WsProjectResponse.FileData buildPartial() {
+          org.sonarqube.ws.WsScanner.WsProjectResponse.FileData result = new org.sonarqube.ws.WsScanner.WsProjectResponse.FileData(this);
+          int from_bitField0_ = bitField0_;
+          int to_bitField0_ = 0;
+          if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+            to_bitField0_ |= 0x00000001;
+          }
+          result.hash_ = hash_;
+          if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+            to_bitField0_ |= 0x00000002;
+          }
+          result.revision_ = revision_;
+          result.bitField0_ = to_bitField0_;
+          onBuilt();
+          return result;
+        }
+
+        public Builder mergeFrom(com.google.protobuf.Message other) {
+          if (other instanceof org.sonarqube.ws.WsScanner.WsProjectResponse.FileData) {
+            return mergeFrom((org.sonarqube.ws.WsScanner.WsProjectResponse.FileData)other);
+          } else {
+            super.mergeFrom(other);
+            return this;
+          }
+        }
+
+        public Builder mergeFrom(org.sonarqube.ws.WsScanner.WsProjectResponse.FileData other) {
+          if (other == org.sonarqube.ws.WsScanner.WsProjectResponse.FileData.getDefaultInstance()) return this;
+          if (other.hasHash()) {
+            bitField0_ |= 0x00000001;
+            hash_ = other.hash_;
+            onChanged();
+          }
+          if (other.hasRevision()) {
+            bitField0_ |= 0x00000002;
+            revision_ = other.revision_;
+            onChanged();
+          }
+          this.mergeUnknownFields(other.unknownFields);
+          onChanged();
+          return this;
+        }
+
+        public final boolean isInitialized() {
+          return true;
+        }
+
+        public Builder mergeFrom(
+            com.google.protobuf.CodedInputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws java.io.IOException {
+          org.sonarqube.ws.WsScanner.WsProjectResponse.FileData parsedMessage = null;
+          try {
+            parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+            parsedMessage = (org.sonarqube.ws.WsScanner.WsProjectResponse.FileData) e.getUnfinishedMessage();
+            throw e;
+          } finally {
+            if (parsedMessage != null) {
+              mergeFrom(parsedMessage);
+            }
+          }
+          return this;
+        }
+        private int bitField0_;
+
+        private java.lang.Object hash_ = "";
+        /**
+         * <code>optional string hash = 1;</code>
+         */
+        public boolean hasHash() {
+          return ((bitField0_ & 0x00000001) == 0x00000001);
+        }
+        /**
+         * <code>optional string hash = 1;</code>
+         */
+        public java.lang.String getHash() {
+          java.lang.Object ref = hash_;
+          if (!(ref instanceof java.lang.String)) {
+            com.google.protobuf.ByteString bs =
+                (com.google.protobuf.ByteString) ref;
+            java.lang.String s = bs.toStringUtf8();
+            if (bs.isValidUtf8()) {
+              hash_ = s;
+            }
+            return s;
+          } else {
+            return (java.lang.String) ref;
+          }
+        }
+        /**
+         * <code>optional string hash = 1;</code>
+         */
+        public com.google.protobuf.ByteString
+            getHashBytes() {
+          java.lang.Object ref = hash_;
+          if (ref instanceof String) {
+            com.google.protobuf.ByteString b = 
+                com.google.protobuf.ByteString.copyFromUtf8(
+                    (java.lang.String) ref);
+            hash_ = b;
+            return b;
+          } else {
+            return (com.google.protobuf.ByteString) ref;
+          }
+        }
+        /**
+         * <code>optional string hash = 1;</code>
+         */
+        public Builder setHash(
+            java.lang.String value) {
+          if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+          hash_ = value;
+          onChanged();
+          return this;
+        }
+        /**
+         * <code>optional string hash = 1;</code>
+         */
+        public Builder clearHash() {
+          bitField0_ = (bitField0_ & ~0x00000001);
+          hash_ = getDefaultInstance().getHash();
+          onChanged();
+          return this;
+        }
+        /**
+         * <code>optional string hash = 1;</code>
+         */
+        public Builder setHashBytes(
+            com.google.protobuf.ByteString value) {
+          if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+          hash_ = value;
+          onChanged();
+          return this;
+        }
+
+        private java.lang.Object revision_ = "";
+        /**
+         * <code>optional string revision = 2;</code>
+         */
+        public boolean hasRevision() {
+          return ((bitField0_ & 0x00000002) == 0x00000002);
+        }
+        /**
+         * <code>optional string revision = 2;</code>
+         */
+        public java.lang.String getRevision() {
+          java.lang.Object ref = revision_;
+          if (!(ref instanceof java.lang.String)) {
+            com.google.protobuf.ByteString bs =
+                (com.google.protobuf.ByteString) ref;
+            java.lang.String s = bs.toStringUtf8();
+            if (bs.isValidUtf8()) {
+              revision_ = s;
+            }
+            return s;
+          } else {
+            return (java.lang.String) ref;
+          }
+        }
+        /**
+         * <code>optional string revision = 2;</code>
+         */
+        public com.google.protobuf.ByteString
+            getRevisionBytes() {
+          java.lang.Object ref = revision_;
+          if (ref instanceof String) {
+            com.google.protobuf.ByteString b = 
+                com.google.protobuf.ByteString.copyFromUtf8(
+                    (java.lang.String) ref);
+            revision_ = b;
+            return b;
+          } else {
+            return (com.google.protobuf.ByteString) ref;
+          }
+        }
+        /**
+         * <code>optional string revision = 2;</code>
+         */
+        public Builder setRevision(
+            java.lang.String value) {
+          if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+          revision_ = value;
+          onChanged();
+          return this;
+        }
+        /**
+         * <code>optional string revision = 2;</code>
+         */
+        public Builder clearRevision() {
+          bitField0_ = (bitField0_ & ~0x00000002);
+          revision_ = getDefaultInstance().getRevision();
+          onChanged();
+          return this;
+        }
+        /**
+         * <code>optional string revision = 2;</code>
+         */
+        public Builder setRevisionBytes(
+            com.google.protobuf.ByteString value) {
+          if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+          revision_ = value;
+          onChanged();
+          return this;
+        }
+
+        // @@protoc_insertion_point(builder_scope:sonarqube.ws.batch.WsProjectResponse.FileData)
+      }
+
+      // @@protoc_insertion_point(class_scope:sonarqube.ws.batch.WsProjectResponse.FileData)
+      private static final org.sonarqube.ws.WsScanner.WsProjectResponse.FileData DEFAULT_INSTANCE;
+      static {
+        DEFAULT_INSTANCE = new org.sonarqube.ws.WsScanner.WsProjectResponse.FileData();
+      }
+
+      public static org.sonarqube.ws.WsScanner.WsProjectResponse.FileData getDefaultInstance() {
+        return DEFAULT_INSTANCE;
+      }
+
+      public static final com.google.protobuf.Parser<FileData> PARSER =
+          new com.google.protobuf.AbstractParser<FileData>() {
+        public FileData parsePartialFrom(
+            com.google.protobuf.CodedInputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws com.google.protobuf.InvalidProtocolBufferException {
+          try {
+            return new FileData(input, extensionRegistry);
+          } catch (RuntimeException e) {
+            if (e.getCause() instanceof
+                com.google.protobuf.InvalidProtocolBufferException) {
+              throw (com.google.protobuf.InvalidProtocolBufferException)
+                  e.getCause();
+            }
+            throw e;
+          }
+        }
+      };
+
+      @java.lang.Override
+      public com.google.protobuf.Parser<FileData> getParserForType() {
+        return PARSER;
+      }
+
+      public org.sonarqube.ws.WsScanner.WsProjectResponse.FileData getDefaultInstanceForType() {
+        return DEFAULT_INSTANCE;
+      }
+
+    }
+
+    private int bitField0_;
+    public static final int TIMESTAMP_FIELD_NUMBER = 1;
+    private long timestamp_;
+    /**
+     * <code>optional int64 timestamp = 1;</code>
+     */
+    public boolean hasTimestamp() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional int64 timestamp = 1;</code>
+     */
+    public long getTimestamp() {
+      return timestamp_;
+    }
+
+    public static final int SETTINGSBYMODULE_FIELD_NUMBER = 2;
+    private static final class SettingsByModuleDefaultEntryHolder {
+      static final com.google.protobuf.MapEntry<
+          java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings> defaultEntry =
+              com.google.protobuf.MapEntry
+              .<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings>newDefaultInstance(
+                  org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_SettingsByModuleEntry_descriptor, 
+                  com.google.protobuf.WireFormat.FieldType.STRING,
+                  "",
+                  com.google.protobuf.WireFormat.FieldType.MESSAGE,
+                  org.sonarqube.ws.WsScanner.WsProjectResponse.Settings.getDefaultInstance());
+    }
+    private com.google.protobuf.MapField<
+        java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings> settingsByModule_;
+    private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings>
+    internalGetSettingsByModule() {
+      if (settingsByModule_ == null) {
+        return com.google.protobuf.MapField.emptyMapField(
+            SettingsByModuleDefaultEntryHolder.defaultEntry);
+     }
+      return settingsByModule_;
+    }
+    /**
+     * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.Settings&gt; settingsByModule = 2;</code>
+     */
+
+    public java.util.Map<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings> getSettingsByModule() {
+      return internalGetSettingsByModule().getMap();
+    }
+
+    public static final int FILEDATABYMODULEANDPATCH_FIELD_NUMBER = 3;
+    private static final class FileDataByModuleAndPatchDefaultEntryHolder {
+      static final com.google.protobuf.MapEntry<
+          java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath> defaultEntry =
+              com.google.protobuf.MapEntry
+              .<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath>newDefaultInstance(
+                  org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByModuleAndPatchEntry_descriptor, 
+                  com.google.protobuf.WireFormat.FieldType.STRING,
+                  "",
+                  com.google.protobuf.WireFormat.FieldType.MESSAGE,
+                  org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath.getDefaultInstance());
+    }
+    private com.google.protobuf.MapField<
+        java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath> fileDataByModuleAndPatch_;
+    private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath>
+    internalGetFileDataByModuleAndPatch() {
+      if (fileDataByModuleAndPatch_ == null) {
+        return com.google.protobuf.MapField.emptyMapField(
+            FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry);
+     }
+      return fileDataByModuleAndPatch_;
+    }
+    /**
+     * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileDataByPath&gt; fileDataByModuleAndPatch = 3;</code>
+     */
+
+    public java.util.Map<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath> getFileDataByModuleAndPatch() {
+      return internalGetFileDataByModuleAndPatch().getMap();
+    }
+
+    public static final int LASTANALYSISDATE_FIELD_NUMBER = 4;
+    private long lastAnalysisDate_;
+    /**
+     * <code>optional int64 lastAnalysisDate = 4;</code>
+     */
+    public boolean hasLastAnalysisDate() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional int64 lastAnalysisDate = 4;</code>
+     */
+    public long getLastAnalysisDate() {
+      return lastAnalysisDate_;
+    }
+
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeInt64(1, timestamp_);
+      }
+      for (java.util.Map.Entry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings> entry
+           : internalGetSettingsByModule().getMap().entrySet()) {
+        com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings>
+        settingsByModule = SettingsByModuleDefaultEntryHolder.defaultEntry.newBuilderForType()
+            .setKey(entry.getKey())
+            .setValue(entry.getValue())
+            .build();
+        output.writeMessage(2, settingsByModule);
+      }
+      for (java.util.Map.Entry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath> entry
+           : internalGetFileDataByModuleAndPatch().getMap().entrySet()) {
+        com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath>
+        fileDataByModuleAndPatch = FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry.newBuilderForType()
+            .setKey(entry.getKey())
+            .setValue(entry.getValue())
+            .build();
+        output.writeMessage(3, fileDataByModuleAndPatch);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeInt64(4, lastAnalysisDate_);
+      }
+      unknownFields.writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(1, timestamp_);
+      }
+      for (java.util.Map.Entry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings> entry
+           : internalGetSettingsByModule().getMap().entrySet()) {
+        com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings>
+        settingsByModule = SettingsByModuleDefaultEntryHolder.defaultEntry.newBuilderForType()
+            .setKey(entry.getKey())
+            .setValue(entry.getValue())
+            .build();
+        size += com.google.protobuf.CodedOutputStream
+            .computeMessageSize(2, settingsByModule);
+      }
+      for (java.util.Map.Entry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath> entry
+           : internalGetFileDataByModuleAndPatch().getMap().entrySet()) {
+        com.google.protobuf.MapEntry<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath>
+        fileDataByModuleAndPatch = FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry.newBuilderForType()
+            .setKey(entry.getKey())
+            .setValue(entry.getValue())
+            .build();
+        size += com.google.protobuf.CodedOutputStream
+            .computeMessageSize(3, fileDataByModuleAndPatch);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(4, lastAnalysisDate_);
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    public static org.sonarqube.ws.WsScanner.WsProjectResponse parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.sonarqube.ws.WsScanner.WsProjectResponse parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.sonarqube.ws.WsScanner.WsProjectResponse parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.sonarqube.ws.WsScanner.WsProjectResponse parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.sonarqube.ws.WsScanner.WsProjectResponse parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.sonarqube.ws.WsScanner.WsProjectResponse parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.sonarqube.ws.WsScanner.WsProjectResponse parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.sonarqube.ws.WsScanner.WsProjectResponse parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.sonarqube.ws.WsScanner.WsProjectResponse parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.sonarqube.ws.WsScanner.WsProjectResponse parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(org.sonarqube.ws.WsScanner.WsProjectResponse prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code sonarqube.ws.batch.WsProjectResponse}
+     *
+     * <pre>
+     * WS api/scanner/project
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:sonarqube.ws.batch.WsProjectResponse)
+        org.sonarqube.ws.WsScanner.WsProjectResponseOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor;
+      }
+
+      @SuppressWarnings({"rawtypes"})
+      protected com.google.protobuf.MapField internalGetMapField(
+          int number) {
+        switch (number) {
+          case 2:
+            return internalGetSettingsByModule();
+          case 3:
+            return internalGetFileDataByModuleAndPatch();
+          default:
+            throw new RuntimeException(
+                "Invalid map field number: " + number);
+        }
+      }
+      @SuppressWarnings({"rawtypes"})
+      protected com.google.protobuf.MapField internalGetMutableMapField(
+          int number) {
+        switch (number) {
+          case 2:
+            return internalGetMutableSettingsByModule();
+          case 3:
+            return internalGetMutableFileDataByModuleAndPatch();
+          default:
+            throw new RuntimeException(
+                "Invalid map field number: " + number);
+        }
+      }
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.sonarqube.ws.WsScanner.WsProjectResponse.class, org.sonarqube.ws.WsScanner.WsProjectResponse.Builder.class);
+      }
+
+      // Construct using org.sonarqube.ws.WsScanner.WsProjectResponse.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        timestamp_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        internalGetMutableSettingsByModule().clear();
+        internalGetMutableFileDataByModuleAndPatch().clear();
+        lastAnalysisDate_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000008);
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.sonarqube.ws.WsScanner.internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor;
+      }
+
+      public org.sonarqube.ws.WsScanner.WsProjectResponse getDefaultInstanceForType() {
+        return org.sonarqube.ws.WsScanner.WsProjectResponse.getDefaultInstance();
+      }
+
+      public org.sonarqube.ws.WsScanner.WsProjectResponse build() {
+        org.sonarqube.ws.WsScanner.WsProjectResponse result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.sonarqube.ws.WsScanner.WsProjectResponse buildPartial() {
+        org.sonarqube.ws.WsScanner.WsProjectResponse result = new org.sonarqube.ws.WsScanner.WsProjectResponse(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.timestamp_ = timestamp_;
+        result.settingsByModule_ = internalGetSettingsByModule();
+        result.settingsByModule_.makeImmutable();
+        result.fileDataByModuleAndPatch_ = internalGetFileDataByModuleAndPatch();
+        result.fileDataByModuleAndPatch_.makeImmutable();
+        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.lastAnalysisDate_ = lastAnalysisDate_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.sonarqube.ws.WsScanner.WsProjectResponse) {
+          return mergeFrom((org.sonarqube.ws.WsScanner.WsProjectResponse)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.sonarqube.ws.WsScanner.WsProjectResponse other) {
+        if (other == org.sonarqube.ws.WsScanner.WsProjectResponse.getDefaultInstance()) return this;
+        if (other.hasTimestamp()) {
+          setTimestamp(other.getTimestamp());
+        }
+        internalGetMutableSettingsByModule().mergeFrom(
+            other.internalGetSettingsByModule());
+        internalGetMutableFileDataByModuleAndPatch().mergeFrom(
+            other.internalGetFileDataByModuleAndPatch());
+        if (other.hasLastAnalysisDate()) {
+          setLastAnalysisDate(other.getLastAnalysisDate());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.sonarqube.ws.WsScanner.WsProjectResponse parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.sonarqube.ws.WsScanner.WsProjectResponse) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private long timestamp_ ;
+      /**
+       * <code>optional int64 timestamp = 1;</code>
+       */
+      public boolean hasTimestamp() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional int64 timestamp = 1;</code>
+       */
+      public long getTimestamp() {
+        return timestamp_;
+      }
+      /**
+       * <code>optional int64 timestamp = 1;</code>
+       */
+      public Builder setTimestamp(long value) {
+        bitField0_ |= 0x00000001;
+        timestamp_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 timestamp = 1;</code>
+       */
+      public Builder clearTimestamp() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        timestamp_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      private com.google.protobuf.MapField<
+          java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings> settingsByModule_;
+      private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings>
+      internalGetSettingsByModule() {
+        if (settingsByModule_ == null) {
+          return com.google.protobuf.MapField.emptyMapField(
+              SettingsByModuleDefaultEntryHolder.defaultEntry);
+       }
+        return settingsByModule_;
+      }
+      private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings>
+      internalGetMutableSettingsByModule() {
+        onChanged();;
+        if (settingsByModule_ == null) {
+          settingsByModule_ = com.google.protobuf.MapField.newMapField(
+              SettingsByModuleDefaultEntryHolder.defaultEntry);
+        }
+        if (!settingsByModule_.isMutable()) {
+          settingsByModule_ = settingsByModule_.copy();
+        }
+        return settingsByModule_;
+      }
+      /**
+       * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.Settings&gt; settingsByModule = 2;</code>
+       */
+      public java.util.Map<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings> getSettingsByModule() {
+        return internalGetSettingsByModule().getMap();
+      }
+      /**
+       * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.Settings&gt; settingsByModule = 2;</code>
+       */
+      public java.util.Map<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.Settings>
+      getMutableSettingsByModule() {
+        return internalGetMutableSettingsByModule().getMutableMap();
+      }
+
+      private com.google.protobuf.MapField<
+          java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath> fileDataByModuleAndPatch_;
+      private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath>
+      internalGetFileDataByModuleAndPatch() {
+        if (fileDataByModuleAndPatch_ == null) {
+          return com.google.protobuf.MapField.emptyMapField(
+              FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry);
+       }
+        return fileDataByModuleAndPatch_;
+      }
+      private com.google.protobuf.MapField<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath>
+      internalGetMutableFileDataByModuleAndPatch() {
+        onChanged();;
+        if (fileDataByModuleAndPatch_ == null) {
+          fileDataByModuleAndPatch_ = com.google.protobuf.MapField.newMapField(
+              FileDataByModuleAndPatchDefaultEntryHolder.defaultEntry);
+        }
+        if (!fileDataByModuleAndPatch_.isMutable()) {
+          fileDataByModuleAndPatch_ = fileDataByModuleAndPatch_.copy();
+        }
+        return fileDataByModuleAndPatch_;
+      }
+      /**
+       * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileDataByPath&gt; fileDataByModuleAndPatch = 3;</code>
+       */
+      public java.util.Map<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath> getFileDataByModuleAndPatch() {
+        return internalGetFileDataByModuleAndPatch().getMap();
+      }
+      /**
+       * <code>map&lt;string, .sonarqube.ws.batch.WsProjectResponse.FileDataByPath&gt; fileDataByModuleAndPatch = 3;</code>
+       */
+      public java.util.Map<java.lang.String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath>
+      getMutableFileDataByModuleAndPatch() {
+        return internalGetMutableFileDataByModuleAndPatch().getMutableMap();
+      }
+
+      private long lastAnalysisDate_ ;
+      /**
+       * <code>optional int64 lastAnalysisDate = 4;</code>
+       */
+      public boolean hasLastAnalysisDate() {
+        return ((bitField0_ & 0x00000008) == 0x00000008);
+      }
+      /**
+       * <code>optional int64 lastAnalysisDate = 4;</code>
+       */
+      public long getLastAnalysisDate() {
+        return lastAnalysisDate_;
+      }
+      /**
+       * <code>optional int64 lastAnalysisDate = 4;</code>
+       */
+      public Builder setLastAnalysisDate(long value) {
+        bitField0_ |= 0x00000008;
+        lastAnalysisDate_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 lastAnalysisDate = 4;</code>
+       */
+      public Builder clearLastAnalysisDate() {
+        bitField0_ = (bitField0_ & ~0x00000008);
+        lastAnalysisDate_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:sonarqube.ws.batch.WsProjectResponse)
+    }
+
+    // @@protoc_insertion_point(class_scope:sonarqube.ws.batch.WsProjectResponse)
+    private static final org.sonarqube.ws.WsScanner.WsProjectResponse DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new org.sonarqube.ws.WsScanner.WsProjectResponse();
+    }
+
+    public static org.sonarqube.ws.WsScanner.WsProjectResponse getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    public static final com.google.protobuf.Parser<WsProjectResponse> PARSER =
+        new com.google.protobuf.AbstractParser<WsProjectResponse>() {
+      public WsProjectResponse parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        try {
+          return new WsProjectResponse(input, extensionRegistry);
+        } catch (RuntimeException e) {
+          if (e.getCause() instanceof
+              com.google.protobuf.InvalidProtocolBufferException) {
+            throw (com.google.protobuf.InvalidProtocolBufferException)
+                e.getCause();
+          }
+          throw e;
+        }
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<WsProjectResponse> getParserForType() {
+      return PARSER;
+    }
+
+    public org.sonarqube.ws.WsScanner.WsProjectResponse getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_sonarqube_ws_batch_WsProjectResponse_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_sonarqube_ws_batch_WsProjectResponse_SettingsByModuleEntry_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_sonarqube_ws_batch_WsProjectResponse_SettingsByModuleEntry_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByModuleAndPatchEntry_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByModuleAndPatchEntry_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_SettingsEntry_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_SettingsEntry_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_FileDataByPathEntry_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_FileDataByPathEntry_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\020ws-scanner.proto\022\022sonarqube.ws.batch\"\364" +
+      "\006\n\021WsProjectResponse\022\021\n\ttimestamp\030\001 \001(\003\022" +
+      "U\n\020settingsByModule\030\002 \003(\0132;.sonarqube.ws" +
+      ".batch.WsProjectResponse.SettingsByModul" +
+      "eEntry\022e\n\030fileDataByModuleAndPatch\030\003 \003(\013" +
+      "2C.sonarqube.ws.batch.WsProjectResponse." +
+      "FileDataByModuleAndPatchEntry\022\030\n\020lastAna" +
+      "lysisDate\030\004 \001(\003\032g\n\025SettingsByModuleEntry" +
+      "\022\013\n\003key\030\001 \001(\t\022=\n\005value\030\002 \001(\0132..sonarqube" +
+      ".ws.batch.WsProjectResponse.Settings:\0028\001",
+      "\032u\n\035FileDataByModuleAndPatchEntry\022\013\n\003key" +
+      "\030\001 \001(\t\022C\n\005value\030\002 \001(\01324.sonarqube.ws.bat" +
+      "ch.WsProjectResponse.FileDataByPath:\0028\001\032" +
+      "\213\001\n\010Settings\022N\n\010settings\030\001 \003(\0132<.sonarqu" +
+      "be.ws.batch.WsProjectResponse.Settings.S" +
+      "ettingsEntry\032/\n\rSettingsEntry\022\013\n\003key\030\001 \001" +
+      "(\t\022\r\n\005value\030\002 \001(\t:\0028\001\032\331\001\n\016FileDataByPath" +
+      "\022`\n\016FileDataByPath\030\001 \003(\0132H.sonarqube.ws." +
+      "batch.WsProjectResponse.FileDataByPath.F" +
+      "ileDataByPathEntry\032e\n\023FileDataByPathEntr",
+      "y\022\013\n\003key\030\001 \001(\t\022=\n\005value\030\002 \001(\0132..sonarqub" +
+      "e.ws.batch.WsProjectResponse.FileData:\0028" +
+      "\001\032*\n\010FileData\022\014\n\004hash\030\001 \001(\t\022\020\n\010revision\030" +
+      "\002 \001(\tB\037\n\020org.sonarqube.wsB\tWsScannerH\001"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+    internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_sonarqube_ws_batch_WsProjectResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+        internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor,
+        new java.lang.String[] { "Timestamp", "SettingsByModule", "FileDataByModuleAndPatch", "LastAnalysisDate", });
+    internal_static_sonarqube_ws_batch_WsProjectResponse_SettingsByModuleEntry_descriptor =
+      internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor.getNestedTypes().get(0);
+    internal_static_sonarqube_ws_batch_WsProjectResponse_SettingsByModuleEntry_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+        internal_static_sonarqube_ws_batch_WsProjectResponse_SettingsByModuleEntry_descriptor,
+        new java.lang.String[] { "Key", "Value", });
+    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByModuleAndPatchEntry_descriptor =
+      internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor.getNestedTypes().get(1);
+    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByModuleAndPatchEntry_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+        internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByModuleAndPatchEntry_descriptor,
+        new java.lang.String[] { "Key", "Value", });
+    internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor =
+      internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor.getNestedTypes().get(2);
+    internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+        internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor,
+        new java.lang.String[] { "Settings", });
+    internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_SettingsEntry_descriptor =
+      internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_descriptor.getNestedTypes().get(0);
+    internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_SettingsEntry_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+        internal_static_sonarqube_ws_batch_WsProjectResponse_Settings_SettingsEntry_descriptor,
+        new java.lang.String[] { "Key", "Value", });
+    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor =
+      internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor.getNestedTypes().get(3);
+    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+        internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor,
+        new java.lang.String[] { "FileDataByPath", });
+    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_FileDataByPathEntry_descriptor =
+      internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_descriptor.getNestedTypes().get(0);
+    internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_FileDataByPathEntry_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+        internal_static_sonarqube_ws_batch_WsProjectResponse_FileDataByPath_FileDataByPathEntry_descriptor,
+        new java.lang.String[] { "Key", "Value", });
+    internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_descriptor =
+      internal_static_sonarqube_ws_batch_WsProjectResponse_descriptor.getNestedTypes().get(4);
+    internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+        internal_static_sonarqube_ws_batch_WsProjectResponse_FileData_descriptor,
+        new java.lang.String[] { "Hash", "Revision", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/sonar-ws/src/main/protobuf/ws-batch.proto b/sonar-ws/src/main/protobuf/ws-batch.proto
deleted file mode 100644 (file)
index cf46d50..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-// SonarQube, open source software quality management tool.
-// Copyright (C) 2008-2015 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.
-
-syntax = "proto2";
-
-package sonarqube.ws.batch;
-
-option java_package = "org.sonarqube.ws";
-option java_outer_classname = "WsBatch";
-
-option optimize_for = SPEED;
-
-// WS api/batch/project
-message WsProjectResponse {
-  optional int64 timestamp = 1;
-  map<string, Settings> settingsByModule = 2;
-  map<string, FileDataByPath> fileDataByModuleAndPatch = 3;
-  optional int64 lastAnalysisDate = 4;
-
-  message Settings {
-    map<string,string> settings = 1;
-  }
-
-  message FileDataByPath {
-    map<string, FileData> FileDataByPath = 1;
-  }
-
-  message FileData {
-    optional string hash = 1;
-    optional string revision = 2;
-  }
-}
diff --git a/sonar-ws/src/main/protobuf/ws-scanner.proto b/sonar-ws/src/main/protobuf/ws-scanner.proto
new file mode 100644 (file)
index 0000000..0f60853
--- /dev/null
@@ -0,0 +1,47 @@
+// SonarQube, open source software quality management tool.
+// Copyright (C) 2008-2015 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.
+
+syntax = "proto2";
+
+package sonarqube.ws.batch;
+
+option java_package = "org.sonarqube.ws";
+option java_outer_classname = "WsScanner";
+
+option optimize_for = SPEED;
+
+// WS api/scanner/project
+message WsProjectResponse {
+  optional int64 timestamp = 1;
+  map<string, Settings> settingsByModule = 2;
+  map<string, FileDataByPath> fileDataByModuleAndPatch = 3;
+  optional int64 lastAnalysisDate = 4;
+
+  message Settings {
+    map<string,string> settings = 1;
+  }
+
+  message FileDataByPath {
+    map<string, FileData> FileDataByPath = 1;
+  }
+
+  message FileData {
+    optional string hash = 1;
+    optional string revision = 2;
+  }
+}