]> source.dussan.org Git - sonarqube.git/commitdiff
refactor ServerComponents into multiple PlatformLevel classes 307/head
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 13 May 2015 09:43:16 +0000 (11:43 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 20 May 2015 08:45:25 +0000 (10:45 +0200)
server/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelSafeMode.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/platform/ComponentContainer.java

index 766a5d1ba386b990e848ca25490b3884b6a95e98..a62ad0d5cc6e0af6e2ae1a133d2f4cabefe4d49c 100644 (file)
  */
 package org.sonar.server.platform;
 
+import java.util.Collection;
+import java.util.List;
+import java.util.Properties;
+
+import javax.annotation.CheckForNull;
+import javax.servlet.ServletContext;
+
 import org.sonar.api.platform.Server;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
+import org.sonar.api.utils.log.Profiler;
 import org.sonar.core.persistence.DatabaseVersion;
 import org.sonar.core.platform.ComponentContainer;
+import org.sonar.server.platform.platformlevel.PlatformLevel;
+import org.sonar.server.platform.platformlevel.PlatformLevel1;
+import org.sonar.server.platform.platformlevel.PlatformLevel2;
+import org.sonar.server.platform.platformlevel.PlatformLevel3;
+import org.sonar.server.platform.platformlevel.PlatformLevel4;
+import org.sonar.server.platform.platformlevel.PlatformLevelSafeMode;
+import org.sonar.server.platform.platformlevel.PlatformLevelStartup;
 
-import javax.annotation.CheckForNull;
-import javax.servlet.ServletContext;
-
-import java.util.Collection;
-import java.util.Properties;
+import com.google.common.collect.Lists;
 
 /**
  * @since 2.2
@@ -40,11 +51,14 @@ public class Platform {
 
   private static final Platform INSTANCE = new Platform();
 
-  private ServerComponents serverComponents;
-  private ComponentContainer level1Container, level2Container, safeModeContainer, level3Container, level4Container;
-  private ComponentContainer currentContainer;
+  private Properties properties;
+  private ServletContext servletContext;
+  private PlatformLevel level1, level2, levelSafeMode, level3, level4;
+  private PlatformLevel currentLevel;
   private boolean dbConnected = false;
   private boolean started = false;
+  private final List<Object> level4AddedComponents = Lists.newArrayList();
+  private final Profiler profiler = Profiler.createIfTrace(Loggers.get(Platform.class));
 
   public Platform() {
   }
@@ -72,11 +86,12 @@ public class Platform {
   }
 
   public void init(Properties properties, ServletContext servletContext) {
-    serverComponents = new ServerComponents(this, properties, servletContext);
+    this.properties = properties;
+    this.servletContext = servletContext;
     if (!dbConnected) {
       startLevel1Container();
       startLevel2Container();
-      currentContainer = level2Container;
+      currentLevel = level2;
       dbConnected = true;
     }
   }
@@ -94,13 +109,13 @@ public class Platform {
     if (requireSafeMode()) {
       LOGGER.info("DB needs migration, entering safe mode");
       startSafeModeContainer();
-      currentContainer = safeModeContainer;
+      currentLevel = levelSafeMode;
       started = true;
     } else {
       startLevel34Containers();
       executeStartupTasks(startup);
       // switch current container last to avoid giving access to a partially initialized container
-      currentContainer = level4Container;
+      currentLevel = level4;
       started = true;
 
       // stop safemode container if it existed
@@ -113,8 +128,9 @@ public class Platform {
   }
 
   protected void restart(Startup startup) {
-    // switch currentContainer on level1 now to avoid exposing a container in the process of stopping
-    currentContainer = level1Container;
+
+    // switch currentLevel on level1 now to avoid exposing a container in the process of stopping
+    currentLevel = level1;
 
     // stop containers
     stopSafeModeContainer();
@@ -124,7 +140,7 @@ public class Platform {
     startLevel2Container();
     startLevel34Containers();
     executeStartupTasks(startup);
-    currentContainer = level4Container;
+    currentLevel = level4;
   }
 
   private boolean requireSafeMode() {
@@ -143,10 +159,10 @@ public class Platform {
     if (!started) {
       return Status.BOOTING;
     }
-    if (safeModeContainer != null && currentContainer == safeModeContainer) {
+    if (levelSafeMode != null && currentLevel == levelSafeMode) {
       return Status.SAFEMODE;
     }
-    if (currentContainer == level4Container) {
+    if (currentLevel == level4) {
       return Status.UP;
     }
     return Status.BOOTING;
@@ -156,30 +172,22 @@ public class Platform {
    * Starts level 1
    */
   private void startLevel1Container() {
-    level1Container = new ComponentContainer();
-    level1Container.addSingletons(serverComponents.level1Components());
-    level1Container.startComponents();
+    level1 = start(new PlatformLevel1(this, properties, servletContext));
   }
 
   /**
    * Starts level 2
    */
   private void startLevel2Container() {
-    level2Container = level1Container.createChild();
-    level2Container.addSingletons(serverComponents.level2Components());
-    level2Container.startComponents();
+    level2 = start(new PlatformLevel2(level1));
   }
 
   /**
    * Starts level 3 and 4
    */
   private void startLevel34Containers() {
-    level3Container = level2Container.createChild();
-    level3Container.addSingletons(serverComponents.level3Components());
-    level3Container.startComponents();
-
-    level4Container = level3Container.createChild();
-    serverComponents.startLevel4Components(level4Container);
+    level3 = start(new PlatformLevel3(level2));
+    level4 = start(new PlatformLevel4(level3, level4AddedComponents));
   }
 
   public void executeStartupTasks() {
@@ -188,23 +196,36 @@ public class Platform {
 
   private void executeStartupTasks(Startup startup) {
     if (startup.ordinal() >= Startup.ALL.ordinal()) {
-      serverComponents.executeStartupTasks(level4Container);
+      new PlatformLevelStartup(level4)
+        .configure()
+        .start()
+        .stop()
+        .destroy();
     }
   }
 
   private void startSafeModeContainer() {
-    safeModeContainer = level2Container.createChild();
-    safeModeContainer.addSingletons(serverComponents.safeModeComponents());
-    safeModeContainer.startComponents();
+    levelSafeMode = start(new PlatformLevelSafeMode(level2));
+  }
+
+  private PlatformLevel start(PlatformLevel platformLevel) {
+    profiler.start();
+    platformLevel.configure();
+    profiler.stopTrace(String.format("%s configured", platformLevel.getName()));
+    profiler.start();
+    platformLevel.start();
+    profiler.stopTrace(String.format("%s started", platformLevel.getName()));
+
+    return platformLevel;
   }
 
   /**
    * Stops level 1
    */
   private void stopLevel1Container() {
-    if (level1Container != null) {
-      level1Container.stopComponents();
-      level1Container = null;
+    if (level1 != null) {
+      level1.stop();
+      level1 = null;
     }
   }
 
@@ -215,11 +236,11 @@ public class Platform {
    * {@link ComponentContainer#stopComponents()}).
    */
   private void stopLevel234Containers() {
-    if (level2Container != null) {
-      level2Container.stopComponents();
-      level2Container = null;
-      level3Container = null;
-      level4Container = null;
+    if (level2 != null) {
+      level2.stop();
+      level2 = null;
+      level3 = null;
+      level4 = null;
     }
   }
 
@@ -230,9 +251,9 @@ public class Platform {
    * see {@link ComponentContainer#stopComponents()}).
    */
   private void stopSafeModeContainer() {
-    if (safeModeContainer != null) {
-      safeModeContainer.stopComponents();
-      safeModeContainer = null;
+    if (levelSafeMode != null) {
+      levelSafeMode.stop();
+      levelSafeMode = null;
     }
   }
 
@@ -247,7 +268,7 @@ public class Platform {
       stopSafeModeContainer();
       stopLevel234Containers();
       stopLevel1Container();
-      currentContainer = null;
+      currentLevel = null;
       dbConnected = false;
       started = false;
     } catch (Exception e) {
@@ -255,12 +276,12 @@ public class Platform {
     }
   }
 
-  public void addComponents(Collection components) {
-    serverComponents.addComponents(components);
+  public void addComponents(Collection<?> components) {
+    level4AddedComponents.addAll(components);
   }
 
   public ComponentContainer getContainer() {
-    return currentContainer;
+    return currentLevel.getContainer();
   }
 
   public Object getComponent(Object key) {
@@ -268,7 +289,7 @@ public class Platform {
   }
 
   public enum Status {
-    BOOTING, SAFEMODE, UP;
+    BOOTING, SAFEMODE, UP
   }
 
   public enum Startup {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
deleted file mode 100644 (file)
index 8350f83..0000000
+++ /dev/null
@@ -1,1029 +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.platform;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Properties;
-
-import javax.annotation.Nullable;
-
-import org.sonar.api.config.EmailSettings;
-import org.sonar.api.issue.action.Actions;
-import org.sonar.api.profiles.AnnotationProfileParser;
-import org.sonar.api.profiles.XMLProfileParser;
-import org.sonar.api.profiles.XMLProfileSerializer;
-import org.sonar.api.resources.Languages;
-import org.sonar.api.resources.ResourceTypes;
-import org.sonar.api.rules.AnnotationRuleParser;
-import org.sonar.api.rules.XMLRuleParser;
-import org.sonar.api.server.rule.RulesDefinitionXmlLoader;
-import org.sonar.api.utils.Durations;
-import org.sonar.api.utils.System2;
-import org.sonar.api.utils.UriReader;
-import org.sonar.api.utils.internal.TempFolderCleaner;
-import org.sonar.core.component.SnapshotPerspectives;
-import org.sonar.core.computation.dbcleaner.DefaultPurgeTask;
-import org.sonar.core.computation.dbcleaner.IndexPurgeListener;
-import org.sonar.core.computation.dbcleaner.ProjectCleaner;
-import org.sonar.core.computation.dbcleaner.period.DefaultPeriodCleaner;
-import org.sonar.core.config.CorePropertyDefinitions;
-import org.sonar.core.config.Logback;
-import org.sonar.core.i18n.DefaultI18n;
-import org.sonar.core.i18n.RuleI18nManager;
-import org.sonar.core.issue.IssueFilterSerializer;
-import org.sonar.core.issue.IssueUpdater;
-import org.sonar.core.issue.workflow.FunctionExecutor;
-import org.sonar.core.issue.workflow.IssueWorkflow;
-import org.sonar.core.measure.db.MeasureFilterDao;
-import org.sonar.core.metric.DefaultMetricFinder;
-import org.sonar.core.notification.DefaultNotificationManager;
-import org.sonar.core.permission.PermissionFacade;
-import org.sonar.core.persistence.DaoUtils;
-import org.sonar.core.persistence.DatabaseVersion;
-import org.sonar.core.persistence.DefaultDatabase;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.persistence.SemaphoreUpdater;
-import org.sonar.core.persistence.SemaphoresImpl;
-import org.sonar.core.platform.ComponentContainer;
-import org.sonar.core.platform.PluginLoader;
-import org.sonar.core.purge.PurgeProfiler;
-import org.sonar.core.qualitygate.db.ProjectQgateAssociationDao;
-import org.sonar.core.qualitygate.db.QualityGateConditionDao;
-import org.sonar.core.qualitygate.db.QualityGateDao;
-import org.sonar.core.resource.DefaultResourcePermissions;
-import org.sonar.core.test.TestPlanPerspectiveLoader;
-import org.sonar.core.test.TestablePerspectiveLoader;
-import org.sonar.core.timemachine.Periods;
-import org.sonar.core.user.DefaultUserFinder;
-import org.sonar.core.user.HibernateUserFinder;
-import org.sonar.core.util.DefaultHttpDownloader;
-import org.sonar.jpa.dao.MeasuresDao;
-import org.sonar.jpa.session.DatabaseSessionFactory;
-import org.sonar.jpa.session.DatabaseSessionProvider;
-import org.sonar.jpa.session.DefaultDatabaseConnector;
-import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory;
-import org.sonar.server.activity.ActivityService;
-import org.sonar.server.activity.RubyQProfileActivityService;
-import org.sonar.server.activity.db.ActivityDao;
-import org.sonar.server.activity.index.ActivityIndex;
-import org.sonar.server.activity.index.ActivityIndexDefinition;
-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.BatchIndex;
-import org.sonar.server.batch.BatchWs;
-import org.sonar.server.batch.GlobalAction;
-import org.sonar.server.batch.IssuesAction;
-import org.sonar.server.batch.ProjectAction;
-import org.sonar.server.batch.ProjectRepositoryLoader;
-import org.sonar.server.batch.UsersAction;
-import org.sonar.server.charts.ChartFactory;
-import org.sonar.server.component.ComponentCleanerService;
-import org.sonar.server.component.ComponentService;
-import org.sonar.server.component.DefaultComponentFinder;
-import org.sonar.server.component.DefaultRubyComponentService;
-import org.sonar.server.component.db.ComponentDao;
-import org.sonar.server.component.db.ComponentIndexDao;
-import org.sonar.server.component.db.ComponentLinkDao;
-import org.sonar.server.component.db.SnapshotDao;
-import org.sonar.server.component.ws.ComponentsWs;
-import org.sonar.server.component.ws.EventsWs;
-import org.sonar.server.project.ws.GhostsAction;
-import org.sonar.server.project.ws.ProjectsWs;
-import org.sonar.server.project.ws.ProvisionedAction;
-import org.sonar.server.component.ws.ResourcesWs;
-import org.sonar.server.computation.ComputationThreadLauncher;
-import org.sonar.server.computation.ReportQueue;
-import org.sonar.server.computation.ReportQueueCleaner;
-import org.sonar.server.computation.db.AnalysisReportDao;
-import org.sonar.server.computation.ws.ComputationWs;
-import org.sonar.server.computation.ws.HistoryAction;
-import org.sonar.server.computation.ws.IsQueueEmptyWs;
-import org.sonar.server.computation.ws.QueueAction;
-import org.sonar.server.computation.ws.SubmitReportAction;
-import org.sonar.server.config.ws.PropertiesWs;
-import org.sonar.server.dashboard.db.DashboardDao;
-import org.sonar.server.dashboard.db.WidgetDao;
-import org.sonar.server.dashboard.db.WidgetPropertyDao;
-import org.sonar.server.dashboard.ws.DashboardsWs;
-import org.sonar.server.db.DatabaseChecker;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.db.EmbeddedDatabaseFactory;
-import org.sonar.server.db.migrations.DatabaseMigrator;
-import org.sonar.server.db.migrations.MigrationSteps;
-import org.sonar.server.db.migrations.PlatformDatabaseMigration;
-import org.sonar.server.db.migrations.PlatformDatabaseMigrationExecutorServiceImpl;
-import org.sonar.server.debt.DebtCharacteristicsXMLImporter;
-import org.sonar.server.debt.DebtModelBackup;
-import org.sonar.server.debt.DebtModelLookup;
-import org.sonar.server.debt.DebtModelOperations;
-import org.sonar.server.debt.DebtModelPluginRepository;
-import org.sonar.server.debt.DebtModelService;
-import org.sonar.server.debt.DebtModelXMLExporter;
-import org.sonar.server.debt.DebtRulesXMLImporter;
-import org.sonar.server.design.db.FileDependencyDao;
-import org.sonar.server.design.ws.DependenciesWs;
-import org.sonar.server.duplication.ws.DuplicationsJsonWriter;
-import org.sonar.server.duplication.ws.DuplicationsParser;
-import org.sonar.server.duplication.ws.DuplicationsWs;
-import org.sonar.server.es.EsClient;
-import org.sonar.server.es.IndexCreator;
-import org.sonar.server.es.IndexDefinitions;
-import org.sonar.server.event.db.EventDao;
-import org.sonar.server.issue.ActionService;
-import org.sonar.server.issue.AddTagsAction;
-import org.sonar.server.issue.AssignAction;
-import org.sonar.server.issue.CommentAction;
-import org.sonar.server.issue.InternalRubyIssueService;
-import org.sonar.server.issue.IssueBulkChangeService;
-import org.sonar.server.issue.IssueChangelogFormatter;
-import org.sonar.server.issue.IssueChangelogService;
-import org.sonar.server.issue.IssueCommentService;
-import org.sonar.server.issue.IssueQueryService;
-import org.sonar.server.issue.IssueService;
-import org.sonar.server.issue.PlanAction;
-import org.sonar.server.issue.RemoveTagsAction;
-import org.sonar.server.issue.ServerIssueStorage;
-import org.sonar.server.issue.SetSeverityAction;
-import org.sonar.server.issue.TransitionAction;
-import org.sonar.server.issue.actionplan.ActionPlanService;
-import org.sonar.server.issue.actionplan.ActionPlanWs;
-import org.sonar.server.issue.db.IssueDao;
-import org.sonar.server.issue.filter.IssueFilterService;
-import org.sonar.server.issue.filter.IssueFilterWriter;
-import org.sonar.server.issue.filter.IssueFilterWs;
-import org.sonar.server.issue.filter.RegisterIssueFilters;
-import org.sonar.server.issue.index.IssueAuthorizationIndexer;
-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.issue.notification.ChangesOnMyIssueNotificationDispatcher;
-import org.sonar.server.issue.notification.DoNotFixNotificationDispatcher;
-import org.sonar.server.issue.notification.IssueChangesEmailTemplate;
-import org.sonar.server.issue.notification.MyNewIssuesEmailTemplate;
-import org.sonar.server.issue.notification.MyNewIssuesNotificationDispatcher;
-import org.sonar.server.issue.notification.NewIssuesEmailTemplate;
-import org.sonar.server.issue.notification.NewIssuesNotificationDispatcher;
-import org.sonar.server.issue.notification.NewIssuesNotificationFactory;
-import org.sonar.server.issue.ws.ComponentTagsAction;
-import org.sonar.server.issue.ws.IssueActionsWriter;
-import org.sonar.server.issue.ws.IssuesWs;
-import org.sonar.server.issue.ws.SetTagsAction;
-import org.sonar.server.language.ws.LanguageWs;
-import org.sonar.server.measure.MeasureFilterEngine;
-import org.sonar.server.measure.MeasureFilterExecutor;
-import org.sonar.server.measure.MeasureFilterFactory;
-import org.sonar.server.measure.persistence.MeasureDao;
-import org.sonar.server.measure.persistence.MetricDao;
-import org.sonar.server.measure.ws.ManualMeasuresWs;
-import org.sonar.server.measure.ws.MetricsWs;
-import org.sonar.server.measure.ws.TimeMachineWs;
-import org.sonar.server.notifications.NotificationCenter;
-import org.sonar.server.notifications.NotificationService;
-import org.sonar.server.permission.InternalPermissionService;
-import org.sonar.server.permission.InternalPermissionTemplateService;
-import org.sonar.server.permission.PermissionFinder;
-import org.sonar.server.permission.ws.PermissionsWs;
-import org.sonar.server.platform.monitoring.DatabaseMonitor;
-import org.sonar.server.platform.monitoring.EsMonitor;
-import org.sonar.server.platform.monitoring.JvmPropertiesMonitor;
-import org.sonar.server.platform.monitoring.PluginsMonitor;
-import org.sonar.server.platform.monitoring.SonarQubeMonitor;
-import org.sonar.server.platform.monitoring.SystemMonitor;
-import org.sonar.server.platform.ws.L10nWs;
-import org.sonar.server.platform.ws.MigrateDbSystemAction;
-import org.sonar.server.platform.ws.ServerWs;
-import org.sonar.server.platform.ws.InfoAction;
-import org.sonar.server.platform.ws.RestartAction;
-import org.sonar.server.platform.ws.StatusAction;
-import org.sonar.server.platform.ws.SystemWs;
-import org.sonar.server.platform.ws.UpgradesAction;
-import org.sonar.server.plugins.InstalledPluginReferentialFactory;
-import org.sonar.server.plugins.PluginDownloader;
-import org.sonar.server.plugins.ServerExtensionInstaller;
-import org.sonar.server.plugins.ServerPluginRepository;
-import org.sonar.server.plugins.ServerPluginExploder;
-import org.sonar.server.plugins.UpdateCenterClient;
-import org.sonar.server.plugins.UpdateCenterMatrixFactory;
-import org.sonar.server.plugins.ws.AvailableAction;
-import org.sonar.server.plugins.ws.CancelAllAction;
-import org.sonar.server.plugins.ws.InstallAction;
-import org.sonar.server.plugins.ws.InstalledAction;
-import org.sonar.server.plugins.ws.PendingAction;
-import org.sonar.server.plugins.ws.PluginUpdateAggregator;
-import org.sonar.server.plugins.ws.PluginWSCommons;
-import org.sonar.server.plugins.ws.PluginsWs;
-import org.sonar.server.plugins.ws.UninstallAction;
-import org.sonar.server.plugins.ws.UpdateAction;
-import org.sonar.server.plugins.ws.UpdatesAction;
-import org.sonar.server.properties.ProjectSettingsFactory;
-import org.sonar.server.qualitygate.QgateProjectFinder;
-import org.sonar.server.qualitygate.QualityGates;
-import org.sonar.server.qualitygate.RegisterQualityGates;
-import org.sonar.server.qualitygate.ws.AppAction;
-import org.sonar.server.qualitygate.ws.CreateConditionAction;
-import org.sonar.server.qualitygate.ws.DeleteConditionAction;
-import org.sonar.server.qualitygate.ws.DeselectAction;
-import org.sonar.server.qualitygate.ws.DestroyAction;
-import org.sonar.server.qualitygate.ws.SelectAction;
-import org.sonar.server.qualitygate.ws.SetAsDefaultAction;
-import org.sonar.server.qualitygate.ws.ShowAction;
-import org.sonar.server.qualitygate.ws.UnsetDefaultAction;
-import org.sonar.server.qualitygate.ws.UpdateConditionAction;
-import org.sonar.server.qualitygate.ws.QGatesWs;
-import org.sonar.server.qualityprofile.BuiltInProfiles;
-import org.sonar.server.qualityprofile.QProfileBackuper;
-import org.sonar.server.qualityprofile.QProfileComparison;
-import org.sonar.server.qualityprofile.QProfileCopier;
-import org.sonar.server.qualityprofile.QProfileExporters;
-import org.sonar.server.qualityprofile.QProfileFactory;
-import org.sonar.server.qualityprofile.QProfileLoader;
-import org.sonar.server.qualityprofile.QProfileLookup;
-import org.sonar.server.qualityprofile.QProfileProjectLookup;
-import org.sonar.server.qualityprofile.QProfileProjectOperations;
-import org.sonar.server.qualityprofile.QProfileReset;
-import org.sonar.server.qualityprofile.QProfileService;
-import org.sonar.server.qualityprofile.QProfiles;
-import org.sonar.server.qualityprofile.RegisterQualityProfiles;
-import org.sonar.server.qualityprofile.RuleActivator;
-import org.sonar.server.qualityprofile.RuleActivatorContextFactory;
-import org.sonar.server.qualityprofile.db.ActiveRuleDao;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
-import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
-import org.sonar.server.qualityprofile.ws.BulkRuleActivationActions;
-import org.sonar.server.qualityprofile.ws.ProfilesWs;
-import org.sonar.server.qualityprofile.ws.ProjectAssociationActions;
-import org.sonar.server.qualityprofile.ws.BackupAction;
-import org.sonar.server.qualityprofile.ws.ChangeParentAction;
-import org.sonar.server.qualityprofile.ws.ChangelogAction;
-import org.sonar.server.qualityprofile.ws.CompareAction;
-import org.sonar.server.qualityprofile.ws.CopyAction;
-import org.sonar.server.qualityprofile.ws.CreateAction;
-import org.sonar.server.qualityprofile.ws.DeleteAction;
-import org.sonar.server.qualityprofile.ws.ExportAction;
-import org.sonar.server.qualityprofile.ws.ExportersAction;
-import org.sonar.server.qualityprofile.ws.ImportersAction;
-import org.sonar.server.qualityprofile.ws.InheritanceAction;
-import org.sonar.server.qualityprofile.ws.ProjectsAction;
-import org.sonar.server.qualityprofile.ws.RenameAction;
-import org.sonar.server.qualityprofile.ws.RestoreAction;
-import org.sonar.server.qualityprofile.ws.RestoreBuiltInAction;
-import org.sonar.server.qualityprofile.ws.SearchAction;
-import org.sonar.server.qualityprofile.ws.SetDefaultAction;
-import org.sonar.server.qualityprofile.ws.QProfilesWs;
-import org.sonar.server.qualityprofile.ws.RuleActivationActions;
-import org.sonar.server.ruby.PlatformRackBridge;
-import org.sonar.server.ruby.PlatformRubyBridge;
-import org.sonar.server.rule.DefaultRuleFinder;
-import org.sonar.server.rule.DeprecatedRulesDefinitionLoader;
-import org.sonar.server.rule.RegisterRules;
-import org.sonar.server.rule.RubyRuleService;
-import org.sonar.server.rule.RuleCreator;
-import org.sonar.server.rule.RuleDefinitionsLoader;
-import org.sonar.server.rule.RuleDeleter;
-import org.sonar.server.rule.RuleOperations;
-import org.sonar.server.rule.RuleRepositories;
-import org.sonar.server.rule.RuleService;
-import org.sonar.server.rule.RuleUpdater;
-import org.sonar.server.rule.db.RuleDao;
-import org.sonar.server.rule.index.RuleIndex;
-import org.sonar.server.rule.index.RuleNormalizer;
-import org.sonar.server.rule.ws.ActiveRuleCompleter;
-import org.sonar.server.rule.ws.RepositoriesAction;
-import org.sonar.server.rule.ws.RuleMapping;
-import org.sonar.server.rule.ws.RulesWs;
-import org.sonar.server.rule.ws.TagsAction;
-import org.sonar.server.search.IndexClient;
-import org.sonar.server.search.IndexQueue;
-import org.sonar.server.search.IndexSynchronizer;
-import org.sonar.server.search.SearchClient;
-import org.sonar.server.source.HtmlSourceDecorator;
-import org.sonar.server.source.SourceService;
-import org.sonar.server.source.db.FileSourceDao;
-import org.sonar.server.source.index.SourceLineIndex;
-import org.sonar.server.source.index.SourceLineIndexDefinition;
-import org.sonar.server.source.index.SourceLineIndexer;
-import org.sonar.server.source.ws.HashAction;
-import org.sonar.server.source.ws.IndexAction;
-import org.sonar.server.source.ws.LinesAction;
-import org.sonar.server.source.ws.RawAction;
-import org.sonar.server.source.ws.ScmAction;
-import org.sonar.server.source.ws.SourcesWs;
-import org.sonar.server.startup.CopyRequirementsFromCharacteristicsToRules;
-import org.sonar.server.startup.GeneratePluginIndex;
-import org.sonar.server.startup.JdbcDriverDeployer;
-import org.sonar.server.startup.LogServerId;
-import org.sonar.server.startup.RegisterDashboards;
-import org.sonar.server.startup.RegisterDebtModel;
-import org.sonar.server.startup.RegisterMetrics;
-import org.sonar.server.startup.RegisterNewMeasureFilters;
-import org.sonar.server.startup.RegisterPermissionTemplates;
-import org.sonar.server.startup.RegisterServletFilters;
-import org.sonar.server.startup.RenameDeprecatedPropertyKeys;
-import org.sonar.server.startup.RenameIssueWidgets;
-import org.sonar.server.startup.ServerMetadataPersister;
-import org.sonar.server.test.CoverageService;
-import org.sonar.server.test.index.TestIndex;
-import org.sonar.server.test.index.TestIndexDefinition;
-import org.sonar.server.test.index.TestIndexer;
-import org.sonar.server.test.ws.CoveredFilesAction;
-import org.sonar.server.test.ws.ListAction;
-import org.sonar.server.test.ws.TestsWs;
-import org.sonar.server.text.MacroInterpreter;
-import org.sonar.server.text.RubyTextService;
-import org.sonar.server.ui.JRubyI18n;
-import org.sonar.server.ui.PageDecorations;
-import org.sonar.server.ui.Views;
-import org.sonar.server.ui.ws.ComponentNavigationAction;
-import org.sonar.server.ui.ws.GlobalNavigationAction;
-import org.sonar.server.ui.ws.NavigationWs;
-import org.sonar.server.ui.ws.SettingsNavigationAction;
-import org.sonar.server.updatecenter.ws.UpdateCenterWs;
-import org.sonar.server.user.DefaultUserService;
-import org.sonar.server.user.DoPrivileged;
-import org.sonar.server.user.GroupMembershipFinder;
-import org.sonar.server.user.GroupMembershipService;
-import org.sonar.server.user.NewUserNotifier;
-import org.sonar.server.user.SecurityRealmFactory;
-import org.sonar.server.user.ThreadLocalUserSession;
-import org.sonar.server.user.UserUpdater;
-import org.sonar.server.user.db.GroupDao;
-import org.sonar.server.user.db.UserDao;
-import org.sonar.server.user.db.UserGroupDao;
-import org.sonar.server.user.index.UserIndex;
-import org.sonar.server.user.index.UserIndexDefinition;
-import org.sonar.server.user.index.UserIndexer;
-import org.sonar.server.user.ws.CurrentAction;
-import org.sonar.server.user.ws.FavoritesWs;
-import org.sonar.server.user.ws.UserPropertiesWs;
-import org.sonar.server.user.ws.UsersWs;
-import org.sonar.server.util.BooleanTypeValidation;
-import org.sonar.server.util.FloatTypeValidation;
-import org.sonar.server.util.IntegerTypeValidation;
-import org.sonar.server.util.StringListTypeValidation;
-import org.sonar.server.util.StringTypeValidation;
-import org.sonar.server.util.TextTypeValidation;
-import org.sonar.server.util.TypeValidations;
-import org.sonar.server.view.index.ViewIndex;
-import org.sonar.server.view.index.ViewIndexDefinition;
-import org.sonar.server.view.index.ViewIndexer;
-import org.sonar.server.ws.ListingWs;
-import org.sonar.server.ws.WebServiceEngine;
-
-import com.google.common.collect.Lists;
-
-class ServerComponents {
-
-  private final Platform platform;
-  private final Properties properties;
-  @Nullable
-  private final Object[] extraRootComponents;
-  private final List<Object> level4AddedComponents = Lists.newArrayList();
-
-  ServerComponents(Platform platform, Properties properties, Object... extraRootComponents) {
-    this.platform = platform;
-    this.properties = properties;
-    this.extraRootComponents = extraRootComponents;
-  }
-
-  /**
-   * All the stuff required to connect to database
-   */
-  Collection<Object> level1Components() {
-    List<Object> components = Lists.newArrayList(platform, properties);
-    addExtraRootComponents(components);
-    components.addAll(Arrays.asList(
-      ServerSettings.class,
-      ServerImpl.class,
-      Logback.class,
-      EmbeddedDatabaseFactory.class,
-      DefaultDatabase.class,
-      DatabaseChecker.class,
-      MyBatis.class,
-      IndexQueue.class,
-      DatabaseServerCompatibility.class,
-      DatabaseVersion.class,
-      PurgeProfiler.class,
-      DefaultServerFileSystem.class,
-      SemaphoreUpdater.class,
-      SemaphoresImpl.class,
-      TempFolderCleaner.class,
-      new TempFolderProvider(),
-      System2.INSTANCE,
-
-      // rack bridges
-      PlatformRackBridge.class,
-
-      // user session
-      ThreadLocalUserSession.class,
-
-      // DB
-      DbClient.class,
-
-      // Elasticsearch
-      SearchClient.class,
-      IndexClient.class,
-      EsClient.class,
-
-      // users
-      GroupDao.class,
-      UserDao.class,
-      UserGroupDao.class,
-
-      // dashboards
-      DashboardDao.class,
-      WidgetDao.class,
-      WidgetPropertyDao.class,
-
-      // rules/qprofiles
-      RuleNormalizer.class,
-      ActiveRuleNormalizer.class,
-      RuleIndex.class,
-      ActiveRuleIndex.class,
-      RuleDao.class,
-      ActiveRuleDao.class,
-
-      // issues
-      IssueIndex.class,
-      IssueDao.class,
-
-      // measures
-      MeasureDao.class,
-      MetricDao.class,
-      MeasureFilterDao.class,
-
-      // components
-      ComponentDao.class,
-      ComponentIndexDao.class,
-      ComponentLinkDao.class,
-      SnapshotDao.class,
-
-      EventDao.class,
-      ActivityDao.class,
-      AnalysisReportDao.class,
-      FileSourceDao.class,
-      FileDependencyDao.class
-      ));
-    components.addAll(CorePropertyDefinitions.all());
-    components.addAll(MigrationSteps.CLASSES);
-    components.addAll(DaoUtils.getDaoClasses());
-    return components;
-  }
-
-  private void addExtraRootComponents(List<Object> components) {
-    if (this.extraRootComponents != null) {
-      for (Object extraRootComponent : this.extraRootComponents) {
-        if (extraRootComponent != null) {
-          components.add(extraRootComponent);
-        }
-      }
-    }
-  }
-
-  /**
-   * The stuff required to display the db upgrade form in webapp.
-   * Needs to be connected to db.
-   */
-  Collection<Object> level2Components() {
-    return Lists.<Object>newArrayList(
-      DefaultServerUpgradeStatus.class,
-      DatabaseMigrator.class,
-
-      // depends on Ruby
-      PlatformRubyBridge.class,
-
-      // plugins
-      ServerPluginRepository.class,
-      ServerPluginExploder.class,
-      PluginLoader.class,
-      InstalledPluginReferentialFactory.class,
-      ServerExtensionInstaller.class,
-
-      // depends on plugins
-      RailsAppsDeployer.class,
-      JRubyI18n.class,
-      DefaultI18n.class,
-      RuleI18nManager.class,
-      Durations.class,
-
-      // DB migration
-      PlatformDatabaseMigrationExecutorServiceImpl.class,
-      PlatformDatabaseMigration.class
-
-      );
-  }
-
-  /**
-   * These components allow minimum services to be provided by SonarQube when database is not up-to-date and
-   * level3/4 components can therefore NOT be loaded. They rely on level1 and level2 components.
-   * <p>
-   * Available components:
-   * <ul>
-   *   <li>WS to query status of the server and upgrade the DB and their dependencies</li>
-   *   <li>WS listing Webservice to allow user to list WebServices available in safemode</li>
-   * </ul>
-   * </p>
-   */
-  public Collection<Object> safeModeComponents() {
-    return Lists.<Object>newArrayList(
-
-      // DB access required by DatabaseSessionFilter wired into ROR
-      DefaultDatabaseConnector.class,
-      ThreadLocalDatabaseSessionFactory.class,
-
-      // Server WS
-      StatusAction.class,
-      MigrateDbSystemAction.class,
-      SystemWs.class,
-
-      // Listing WS
-      ListingWs.class,
-
-      // WS engine
-      WebServiceEngine.class
-      );
-  }
-
-  /**
-   * The core components that complete the initialization of database
-   * when its schema is up-to-date.
-   */
-  Collection<Object> level3Components() {
-    return Lists.newArrayList(
-      PersistentSettings.class,
-      DefaultDatabaseConnector.class,
-      ThreadLocalDatabaseSessionFactory.class,
-      new DatabaseSessionProvider(),
-      ServerMetadataPersister.class,
-      DefaultHttpDownloader.class,
-      UriReader.class,
-      ServerIdGenerator.class
-      );
-  }
-
-  void startLevel4Components(ComponentContainer pico) {
-    pico.addSingleton(PluginDownloader.class);
-    pico.addSingleton(ChartFactory.class);
-    pico.addSingleton(Views.class);
-    pico.addSingleton(ResourceTypes.class);
-    pico.addSingleton(SettingsChangeNotifier.class);
-    pico.addSingleton(PageDecorations.class);
-    pico.addSingleton(DefaultResourcePermissions.class);
-    pico.addSingleton(Periods.class);
-    pico.addSingleton(ServerWs.class);
-    pico.addSingleton(BackendCleanup.class);
-    pico.addSingleton(IndexDefinitions.class);
-    pico.addSingleton(IndexCreator.class);
-
-    // Activity
-    pico.addSingleton(ActivityService.class);
-    pico.addSingleton(ActivityIndexDefinition.class);
-    pico.addSingleton(ActivityIndexer.class);
-    pico.addSingleton(ActivityIndex.class);
-
-    // batch
-    pico.addSingleton(BatchIndex.class);
-    pico.addSingleton(GlobalAction.class);
-    pico.addSingleton(ProjectAction.class);
-    pico.addSingleton(ProjectRepositoryLoader.class);
-    pico.addSingleton(SubmitReportAction.class);
-    pico.addSingleton(IssuesAction.class);
-    pico.addSingleton(UsersAction.class);
-    pico.addSingleton(BatchWs.class);
-
-    // Dashboard
-    pico.addSingleton(DashboardsWs.class);
-    pico.addSingleton(org.sonar.server.dashboard.ws.ShowAction.class);
-
-    // update center
-    pico.addSingleton(UpdateCenterClient.class);
-    pico.addSingleton(UpdateCenterMatrixFactory.class);
-    pico.addSingleton(UpdateCenterWs.class);
-
-    // quality profile
-    pico.addSingleton(XMLProfileParser.class);
-    pico.addSingleton(XMLProfileSerializer.class);
-    pico.addSingleton(AnnotationProfileParser.class);
-    pico.addSingleton(QProfiles.class);
-    pico.addSingleton(QProfileLookup.class);
-    pico.addSingleton(QProfileProjectOperations.class);
-    pico.addSingleton(QProfileProjectLookup.class);
-    pico.addSingleton(QProfileComparison.class);
-    pico.addSingleton(BuiltInProfiles.class);
-    pico.addSingleton(RestoreBuiltInAction.class);
-    pico.addSingleton(SearchAction.class);
-    pico.addSingleton(SetDefaultAction.class);
-    pico.addSingleton(ProjectsAction.class);
-    pico.addSingleton(DeleteAction.class);
-    pico.addSingleton(RenameAction.class);
-    pico.addSingleton(CopyAction.class);
-    pico.addSingleton(BackupAction.class);
-    pico.addSingleton(RestoreAction.class);
-    pico.addSingleton(CreateAction.class);
-    pico.addSingleton(ImportersAction.class);
-    pico.addSingleton(InheritanceAction.class);
-    pico.addSingleton(ChangeParentAction.class);
-    pico.addSingleton(ChangelogAction.class);
-    pico.addSingleton(CompareAction.class);
-    pico.addSingleton(ExportAction.class);
-    pico.addSingleton(ExportersAction.class);
-    pico.addSingleton(QProfilesWs.class);
-    pico.addSingleton(ProfilesWs.class);
-    pico.addSingleton(RuleActivationActions.class);
-    pico.addSingleton(BulkRuleActivationActions.class);
-    pico.addSingleton(ProjectAssociationActions.class);
-    pico.addSingleton(RuleActivator.class);
-    pico.addSingleton(QProfileLoader.class);
-    pico.addSingleton(QProfileExporters.class);
-    pico.addSingleton(QProfileService.class);
-    pico.addSingleton(RuleActivatorContextFactory.class);
-    pico.addSingleton(QProfileFactory.class);
-    pico.addSingleton(QProfileCopier.class);
-    pico.addSingleton(QProfileBackuper.class);
-    pico.addSingleton(QProfileReset.class);
-    pico.addSingleton(RubyQProfileActivityService.class);
-
-    // rule
-    pico.addSingleton(AnnotationRuleParser.class);
-    pico.addSingleton(XMLRuleParser.class);
-    pico.addSingleton(DefaultRuleFinder.class);
-    pico.addSingleton(RuleOperations.class);
-    pico.addSingleton(RubyRuleService.class);
-    pico.addSingleton(RuleRepositories.class);
-    pico.addSingleton(DeprecatedRulesDefinitionLoader.class);
-    pico.addSingleton(RuleDefinitionsLoader.class);
-    pico.addSingleton(RulesDefinitionXmlLoader.class);
-    pico.addSingleton(RuleService.class);
-    pico.addSingleton(RuleUpdater.class);
-    pico.addSingleton(RuleCreator.class);
-    pico.addSingleton(RuleDeleter.class);
-    pico.addSingleton(org.sonar.server.rule.ws.UpdateAction.class);
-    pico.addSingleton(RulesWs.class);
-    pico.addSingleton(org.sonar.server.rule.ws.SearchAction.class);
-    pico.addSingleton(org.sonar.server.rule.ws.ShowAction.class);
-    pico.addSingleton(org.sonar.server.rule.ws.CreateAction.class);
-    pico.addSingleton(org.sonar.server.rule.ws.DeleteAction.class);
-    pico.addSingleton(TagsAction.class);
-    pico.addSingleton(RuleMapping.class);
-    pico.addSingleton(ActiveRuleCompleter.class);
-    pico.addSingleton(RepositoriesAction.class);
-    pico.addSingleton(org.sonar.server.rule.ws.AppAction.class);
-
-    // languages
-    pico.addSingleton(Languages.class);
-    pico.addSingleton(LanguageWs.class);
-    pico.addSingleton(org.sonar.server.language.ws.ListAction.class);
-
-    // activity
-    pico.addSingleton(ActivitiesWs.class);
-    pico.addSingleton(org.sonar.server.activity.ws.SearchAction.class);
-    pico.addSingleton(ActivityMapping.class);
-
-    // measure
-    pico.addComponent(MeasuresDao.class, false);
-    pico.addSingleton(MeasureFilterFactory.class);
-    pico.addSingleton(MeasureFilterExecutor.class);
-    pico.addSingleton(MeasureFilterEngine.class);
-    pico.addSingleton(DefaultMetricFinder.class);
-    pico.addSingleton(ServerLifecycleNotifier.class);
-    pico.addSingleton(TimeMachineWs.class);
-    pico.addSingleton(ManualMeasuresWs.class);
-    pico.addSingleton(MetricsWs.class);
-
-    // quality gates
-    pico.addSingleton(QualityGateDao.class);
-    pico.addSingleton(QualityGateConditionDao.class);
-    pico.addSingleton(QualityGates.class);
-    pico.addSingleton(ProjectQgateAssociationDao.class);
-    pico.addSingleton(QgateProjectFinder.class);
-
-    pico.addSingleton(org.sonar.server.qualitygate.ws.ListAction.class);
-    pico.addSingleton(org.sonar.server.qualitygate.ws.SearchAction.class);
-    pico.addSingleton(ShowAction.class);
-    pico.addSingleton(org.sonar.server.qualitygate.ws.CreateAction.class);
-    pico.addSingleton(org.sonar.server.qualitygate.ws.RenameAction.class);
-    pico.addSingleton(org.sonar.server.qualitygate.ws.CopyAction.class);
-    pico.addSingleton(DestroyAction.class);
-    pico.addSingleton(SetAsDefaultAction.class);
-    pico.addSingleton(UnsetDefaultAction.class);
-    pico.addSingleton(SelectAction.class);
-    pico.addSingleton(DeselectAction.class);
-    pico.addSingleton(CreateConditionAction.class);
-    pico.addSingleton(DeleteConditionAction.class);
-    pico.addSingleton(UpdateConditionAction.class);
-    pico.addSingleton(AppAction.class);
-    pico.addSingleton(QGatesWs.class);
-
-    // web services
-    pico.addSingleton(WebServiceEngine.class);
-    pico.addSingleton(ListingWs.class);
-
-    // localization
-    pico.addSingleton(L10nWs.class);
-
-    // authentication
-    pico.addSingleton(AuthenticationWs.class);
-
-    // users
-    pico.addSingleton(SecurityRealmFactory.class);
-    pico.addSingleton(HibernateUserFinder.class);
-    pico.addSingleton(NewUserNotifier.class);
-    pico.addSingleton(DefaultUserFinder.class);
-    pico.addSingleton(DefaultUserService.class);
-    pico.addSingleton(UsersWs.class);
-    pico.addSingleton(org.sonar.server.user.ws.CreateAction.class);
-    pico.addSingleton(org.sonar.server.user.ws.UpdateAction.class);
-    pico.addSingleton(org.sonar.server.user.ws.DeactivateAction.class);
-    pico.addSingleton(org.sonar.server.user.ws.ChangePasswordAction.class);
-    pico.addSingleton(CurrentAction.class);
-    pico.addSingleton(org.sonar.server.user.ws.SearchAction.class);
-    pico.addSingleton(org.sonar.server.user.ws.GroupsAction.class);
-    pico.addSingleton(org.sonar.server.issue.ws.AuthorsAction.class);
-    pico.addSingleton(FavoritesWs.class);
-    pico.addSingleton(UserPropertiesWs.class);
-    pico.addSingleton(UserIndexDefinition.class);
-    pico.addSingleton(UserIndexer.class);
-    pico.addSingleton(UserIndex.class);
-    pico.addSingleton(UserUpdater.class);
-
-    // groups
-    pico.addSingleton(GroupMembershipService.class);
-    pico.addSingleton(GroupMembershipFinder.class);
-
-    // permissions
-    pico.addSingleton(PermissionFacade.class);
-    pico.addSingleton(InternalPermissionService.class);
-    pico.addSingleton(InternalPermissionTemplateService.class);
-    pico.addSingleton(PermissionFinder.class);
-    pico.addSingleton(PermissionsWs.class);
-
-    // components
-    pico.addSingleton(DefaultComponentFinder.class);
-    pico.addSingleton(DefaultRubyComponentService.class);
-    pico.addSingleton(ComponentService.class);
-    pico.addSingleton(ResourcesWs.class);
-    pico.addSingleton(ComponentsWs.class);
-    pico.addSingleton(ProjectsWs.class);
-    pico.addSingleton(org.sonar.server.component.ws.AppAction.class);
-    pico.addSingleton(org.sonar.server.component.ws.SearchAction.class);
-    pico.addSingleton(EventsWs.class);
-    pico.addSingleton(ComponentCleanerService.class);
-    pico.addSingleton(ProvisionedAction.class);
-    pico.addSingleton(GhostsAction.class);
-
-    // views
-    pico.addSingleton(ViewIndexDefinition.class);
-    pico.addSingleton(ViewIndexer.class);
-    pico.addSingleton(ViewIndex.class);
-
-    // issues
-    pico.addSingleton(IssueIndexDefinition.class);
-    pico.addSingleton(IssueIndexer.class);
-    pico.addSingleton(IssueAuthorizationIndexer.class);
-    pico.addSingleton(ServerIssueStorage.class);
-    pico.addSingleton(IssueUpdater.class);
-    pico.addSingleton(FunctionExecutor.class);
-    pico.addSingleton(IssueWorkflow.class);
-    pico.addSingleton(IssueCommentService.class);
-    pico.addSingleton(InternalRubyIssueService.class);
-    pico.addSingleton(IssueChangelogService.class);
-    pico.addSingleton(ActionService.class);
-    pico.addSingleton(Actions.class);
-    pico.addSingleton(IssueBulkChangeService.class);
-    pico.addSingleton(IssueChangelogFormatter.class);
-    pico.addSingleton(IssuesWs.class);
-    pico.addSingleton(org.sonar.server.issue.ws.ShowAction.class);
-    pico.addSingleton(org.sonar.server.issue.ws.SearchAction.class);
-    pico.addSingleton(org.sonar.server.issue.ws.TagsAction.class);
-    pico.addSingleton(SetTagsAction.class);
-    pico.addSingleton(ComponentTagsAction.class);
-    pico.addSingleton(IssueService.class);
-    pico.addSingleton(IssueActionsWriter.class);
-    pico.addSingleton(IssueQueryService.class);
-    pico.addSingleton(NewIssuesEmailTemplate.class);
-    pico.addSingleton(MyNewIssuesEmailTemplate.class);
-    pico.addSingleton(IssueChangesEmailTemplate.class);
-    pico.addSingleton(ChangesOnMyIssueNotificationDispatcher.class);
-    pico.addSingleton(ChangesOnMyIssueNotificationDispatcher.newMetadata());
-    pico.addSingleton(NewIssuesNotificationDispatcher.class);
-    pico.addSingleton(NewIssuesNotificationDispatcher.newMetadata());
-    pico.addSingleton(MyNewIssuesNotificationDispatcher.class);
-    pico.addSingleton(MyNewIssuesNotificationDispatcher.newMetadata());
-    pico.addSingleton(DoNotFixNotificationDispatcher.class);
-    pico.addSingleton(DoNotFixNotificationDispatcher.newMetadata());
-    pico.addSingleton(NewIssuesNotificationFactory.class);
-
-    // issue filters
-    pico.addSingleton(IssueFilterService.class);
-    pico.addSingleton(IssueFilterSerializer.class);
-    pico.addSingleton(IssueFilterWs.class);
-    pico.addSingleton(IssueFilterWriter.class);
-    pico.addSingleton(org.sonar.server.issue.filter.AppAction.class);
-    pico.addSingleton(org.sonar.server.issue.filter.ShowAction.class);
-    pico.addSingleton(org.sonar.server.issue.filter.FavoritesAction.class);
-
-    // action plan
-    pico.addSingleton(ActionPlanWs.class);
-    pico.addSingleton(ActionPlanService.class);
-
-    // issues actions
-    pico.addSingleton(AssignAction.class);
-    pico.addSingleton(PlanAction.class);
-    pico.addSingleton(SetSeverityAction.class);
-    pico.addSingleton(CommentAction.class);
-    pico.addSingleton(TransitionAction.class);
-    pico.addSingleton(AddTagsAction.class);
-    pico.addSingleton(RemoveTagsAction.class);
-
-    // technical debt
-    pico.addSingleton(DebtModelService.class);
-    pico.addSingleton(DebtModelOperations.class);
-    pico.addSingleton(DebtModelLookup.class);
-    pico.addSingleton(DebtModelBackup.class);
-    pico.addSingleton(DebtModelPluginRepository.class);
-    pico.addSingleton(DebtModelXMLExporter.class);
-    pico.addSingleton(DebtRulesXMLImporter.class);
-    pico.addSingleton(DebtCharacteristicsXMLImporter.class);
-
-    // source
-    pico.addSingleton(HtmlSourceDecorator.class);
-    pico.addSingleton(SourceService.class);
-    pico.addSingleton(SourcesWs.class);
-    pico.addSingleton(org.sonar.server.source.ws.ShowAction.class);
-    pico.addSingleton(LinesAction.class);
-    pico.addSingleton(HashAction.class);
-    pico.addSingleton(RawAction.class);
-    pico.addSingleton(IndexAction.class);
-    pico.addSingleton(ScmAction.class);
-    pico.addSingleton(SourceLineIndexDefinition.class);
-    pico.addSingleton(SourceLineIndex.class);
-    pico.addSingleton(SourceLineIndexer.class);
-
-    // Duplications
-    pico.addSingleton(DuplicationsParser.class);
-    pico.addSingleton(DuplicationsWs.class);
-    pico.addSingleton(DuplicationsJsonWriter.class);
-    pico.addSingleton(org.sonar.server.duplication.ws.ShowAction.class);
-
-    // text
-    pico.addSingleton(MacroInterpreter.class);
-    pico.addSingleton(RubyTextService.class);
-
-    // Notifications
-    pico.addSingleton(EmailSettings.class);
-    pico.addSingleton(NotificationService.class);
-    pico.addSingleton(NotificationCenter.class);
-    pico.addSingleton(DefaultNotificationManager.class);
-
-    // Tests
-    pico.addSingleton(CoverageService.class);
-    pico.addSingleton(TestsWs.class);
-    pico.addSingleton(CoveredFilesAction.class);
-    pico.addSingleton(ListAction.class);
-    pico.addSingleton(TestIndexDefinition.class);
-    pico.addSingleton(TestIndex.class);
-    pico.addSingleton(TestIndexer.class);
-
-    // Properties
-    pico.addSingleton(PropertiesWs.class);
-
-    // graphs and perspective related classes
-    pico.addSingleton(TestablePerspectiveLoader.class);
-    pico.addSingleton(TestPlanPerspectiveLoader.class);
-    pico.addSingleton(SnapshotPerspectives.class);
-
-    // Type validation
-    pico.addSingleton(TypeValidations.class);
-    pico.addSingleton(IntegerTypeValidation.class);
-    pico.addSingleton(FloatTypeValidation.class);
-    pico.addSingleton(BooleanTypeValidation.class);
-    pico.addSingleton(TextTypeValidation.class);
-    pico.addSingleton(StringTypeValidation.class);
-    pico.addSingleton(StringListTypeValidation.class);
-
-    // Design
-    pico.addSingleton(DependenciesWs.class);
-    pico.addSingleton(org.sonar.server.design.ws.ShowAction.class);
-
-    // System
-    pico.addSingletons(Arrays.asList(
-      RestartAction.class,
-      InfoAction.class,
-      UpgradesAction.class,
-      MigrateDbSystemAction.class,
-      StatusAction.class,
-      SystemWs.class,
-      SystemMonitor.class,
-      SonarQubeMonitor.class,
-      EsMonitor.class,
-      PluginsMonitor.class,
-      JvmPropertiesMonitor.class,
-      DatabaseMonitor.class
-      ));
-
-    // Plugins WS
-    pico.addSingleton(PluginWSCommons.class);
-    pico.addSingleton(PluginUpdateAggregator.class);
-    pico.addSingleton(InstalledAction.class);
-    pico.addSingleton(AvailableAction.class);
-    pico.addSingleton(UpdatesAction.class);
-    pico.addSingleton(PendingAction.class);
-    pico.addSingleton(InstallAction.class);
-    pico.addSingleton(UpdateAction.class);
-    pico.addSingleton(UninstallAction.class);
-    pico.addSingleton(CancelAllAction.class);
-    pico.addSingleton(PluginsWs.class);
-
-    // Compute engine
-    pico.addSingleton(ReportQueue.class);
-    pico.addSingleton(ComputationThreadLauncher.class);
-    pico.addSingleton(ComputationWs.class);
-    pico.addSingleton(IsQueueEmptyWs.class);
-    pico.addSingleton(QueueAction.class);
-    pico.addSingleton(HistoryAction.class);
-    pico.addSingleton(DefaultPeriodCleaner.class);
-    pico.addSingleton(DefaultPurgeTask.class);
-    pico.addSingleton(ProjectCleaner.class);
-    pico.addSingleton(ProjectSettingsFactory.class);
-    pico.addSingleton(IndexPurgeListener.class);
-
-    // UI
-    pico.addSingleton(GlobalNavigationAction.class);
-    pico.addSingleton(SettingsNavigationAction.class);
-    pico.addSingleton(ComponentNavigationAction.class);
-    pico.addSingleton(NavigationWs.class);
-
-    for (Object components : level4AddedComponents) {
-      pico.addSingleton(components);
-    }
-
-    ServerExtensionInstaller extensionInstaller = pico.getComponentByType(ServerExtensionInstaller.class);
-    extensionInstaller.installExtensions(pico);
-
-    pico.startComponents();
-  }
-
-  void addComponents(Collection components) {
-    this.level4AddedComponents.addAll(components);
-  }
-
-  public void executeStartupTasks(ComponentContainer pico) {
-    final ComponentContainer startupContainer = pico.createChild();
-    startupContainer.addSingleton(IndexSynchronizer.class);
-    startupContainer.addSingleton(RegisterMetrics.class);
-    startupContainer.addSingleton(RegisterQualityGates.class);
-    startupContainer.addSingleton(RegisterRules.class);
-    startupContainer.addSingleton(RegisterQualityProfiles.class);
-    startupContainer.addSingleton(JdbcDriverDeployer.class);
-    startupContainer.addSingleton(RegisterDebtModel.class);
-    startupContainer.addSingleton(GeneratePluginIndex.class);
-    startupContainer.addSingleton(RegisterNewMeasureFilters.class);
-    startupContainer.addSingleton(RegisterDashboards.class);
-    startupContainer.addSingleton(RegisterPermissionTemplates.class);
-    startupContainer.addSingleton(RenameDeprecatedPropertyKeys.class);
-    startupContainer.addSingleton(LogServerId.class);
-    startupContainer.addSingleton(RegisterServletFilters.class);
-    startupContainer.addSingleton(CopyRequirementsFromCharacteristicsToRules.class);
-    startupContainer.addSingleton(ReportQueueCleaner.class);
-    startupContainer.addSingleton(RegisterIssueFilters.class);
-    startupContainer.addSingleton(RenameIssueWidgets.class);
-
-    DoPrivileged.execute(new DoPrivileged.Task(startupContainer.getComponentByType(ThreadLocalUserSession.class)) {
-      @Override
-      protected void doPrivileged() {
-        startupContainer.getComponentByType(IndexSynchronizer.class).executeDeprecated();
-        startupContainer.startComponents();
-        startupContainer.getComponentByType(IndexSynchronizer.class).execute();
-        startupContainer.getComponentByType(ServerLifecycleNotifier.class).notifyStart();
-      }
-    });
-
-    // Do not put the following statements in a finally block.
-    // It would hide the possible exception raised during startup
-    // See SONAR-3107
-    startupContainer.stopComponents();
-
-    pico.getComponentByType(DatabaseSessionFactory.class).clear();
-    pico.removeChild();
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel.java
new file mode 100644 (file)
index 0000000..dbb30df
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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.platform.platformlevel;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.sonar.core.platform.ComponentContainer;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public abstract class PlatformLevel {
+  private final String name;
+  @Nullable
+  private final PlatformLevel parent;
+  private final ComponentContainer container;
+
+  public PlatformLevel(String name) {
+    this.name = name;
+    this.parent = null;
+    this.container = createContainer(null);
+  }
+
+  public PlatformLevel(String name, @Nonnull PlatformLevel parent) {
+    this.name = checkNotNull(name);
+    this.parent = checkNotNull(parent);
+    this.container = createContainer(parent.container);
+  }
+
+  public ComponentContainer getContainer() {
+    return container;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * Intended to be override by subclasses if needed
+   */
+  protected ComponentContainer createContainer(@Nullable ComponentContainer parent) {
+    if (parent == null) {
+      return new ComponentContainer();
+    }
+    return parent.createChild();
+  }
+
+  public abstract PlatformLevel configure();
+
+  /**
+   * Intended to be override by subclasses if needed
+   */
+  public PlatformLevel start() {
+    container.startComponents();
+
+    return this;
+  }
+
+  /**
+   * Intended to be override by subclasses if needed
+   */
+  public PlatformLevel stop() {
+    container.stopComponents();
+
+    return this;
+  }
+
+  /**
+   * Intended to be override by subclasses if needed
+   */
+  public PlatformLevel destroy() {
+    if (parent != null) {
+      parent.container.removeChild();
+    }
+    return this;
+  }
+
+  protected void add(@Nullable Object object, boolean singleton) {
+    if (object != null) {
+      container.addComponent(object, singleton);
+    }
+  }
+
+  protected <T> T getComponentByType(Class<T> tClass) {
+    return container.getComponentByType(tClass);
+  }
+
+  protected void add(Object... objects) {
+    for (Object object : objects) {
+      if (object != null) {
+        container.addComponent(object, true);
+      }
+    }
+  }
+
+  protected void addAll(Collection<?> objects) {
+    add(objects.toArray(new Object[objects.size()]));
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java
new file mode 100644 (file)
index 0000000..276f0e0
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * 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.platform.platformlevel;
+
+import java.util.Properties;
+
+import javax.annotation.Nullable;
+
+import org.sonar.api.utils.System2;
+import org.sonar.api.utils.internal.TempFolderCleaner;
+import org.sonar.core.config.CorePropertyDefinitions;
+import org.sonar.core.config.Logback;
+import org.sonar.core.measure.db.MeasureFilterDao;
+import org.sonar.core.persistence.DaoUtils;
+import org.sonar.core.persistence.DatabaseVersion;
+import org.sonar.core.persistence.DefaultDatabase;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.persistence.SemaphoreUpdater;
+import org.sonar.core.persistence.SemaphoresImpl;
+import org.sonar.core.purge.PurgeProfiler;
+import org.sonar.server.activity.db.ActivityDao;
+import org.sonar.server.component.db.ComponentDao;
+import org.sonar.server.component.db.ComponentIndexDao;
+import org.sonar.server.component.db.ComponentLinkDao;
+import org.sonar.server.component.db.SnapshotDao;
+import org.sonar.server.computation.db.AnalysisReportDao;
+import org.sonar.server.dashboard.db.DashboardDao;
+import org.sonar.server.dashboard.db.WidgetDao;
+import org.sonar.server.dashboard.db.WidgetPropertyDao;
+import org.sonar.server.db.DatabaseChecker;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.db.EmbeddedDatabaseFactory;
+import org.sonar.server.db.migrations.MigrationSteps;
+import org.sonar.server.design.db.FileDependencyDao;
+import org.sonar.server.es.EsClient;
+import org.sonar.server.event.db.EventDao;
+import org.sonar.server.issue.db.IssueDao;
+import org.sonar.server.issue.index.IssueIndex;
+import org.sonar.server.measure.persistence.MeasureDao;
+import org.sonar.server.measure.persistence.MetricDao;
+import org.sonar.server.platform.DatabaseServerCompatibility;
+import org.sonar.server.platform.DefaultServerFileSystem;
+import org.sonar.server.platform.Platform;
+import org.sonar.server.platform.ServerImpl;
+import org.sonar.server.platform.ServerSettings;
+import org.sonar.server.platform.TempFolderProvider;
+import org.sonar.server.qualityprofile.db.ActiveRuleDao;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
+import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
+import org.sonar.server.ruby.PlatformRackBridge;
+import org.sonar.server.rule.db.RuleDao;
+import org.sonar.server.rule.index.RuleIndex;
+import org.sonar.server.rule.index.RuleNormalizer;
+import org.sonar.server.search.IndexClient;
+import org.sonar.server.search.IndexQueue;
+import org.sonar.server.search.SearchClient;
+import org.sonar.server.source.db.FileSourceDao;
+import org.sonar.server.user.ThreadLocalUserSession;
+import org.sonar.server.user.db.GroupDao;
+import org.sonar.server.user.db.UserDao;
+import org.sonar.server.user.db.UserGroupDao;
+
+public class PlatformLevel1 extends PlatformLevel {
+  private final Platform platform;
+  private final Properties properties;
+  @Nullable
+  private final Object[] extraRootComponents;
+
+  public PlatformLevel1(Platform platform, Properties properties, Object... extraRootComponents) {
+    super("level1");
+    this.platform = platform;
+    this.properties = properties;
+    this.extraRootComponents = extraRootComponents;
+  }
+
+  @Override
+  public PlatformLevel configure() {
+    add(platform, properties);
+    addExtraRootComponents();
+    add(
+      ServerSettings.class,
+      ServerImpl.class,
+      Logback.class,
+      EmbeddedDatabaseFactory.class,
+      DefaultDatabase.class,
+      DatabaseChecker.class,
+      MyBatis.class,
+      IndexQueue.class,
+      DatabaseServerCompatibility.class,
+      DatabaseVersion.class,
+      PurgeProfiler.class,
+      DefaultServerFileSystem.class,
+      SemaphoreUpdater.class,
+      SemaphoresImpl.class,
+      TempFolderCleaner.class,
+      new TempFolderProvider(),
+      System2.INSTANCE,
+
+      // rack bridges
+      PlatformRackBridge.class,
+
+      // user session
+      ThreadLocalUserSession.class,
+
+      // DB
+      DbClient.class,
+
+      // Elasticsearch
+      SearchClient.class,
+      IndexClient.class,
+      EsClient.class,
+
+      // users
+      GroupDao.class,
+      UserDao.class,
+      UserGroupDao.class,
+
+      // dashboards
+      DashboardDao.class,
+      WidgetDao.class,
+      WidgetPropertyDao.class,
+
+      // rules/qprofiles
+      RuleNormalizer.class,
+      ActiveRuleNormalizer.class,
+      RuleIndex.class,
+      ActiveRuleIndex.class,
+      RuleDao.class,
+      ActiveRuleDao.class,
+
+      // issues
+      IssueIndex.class,
+      IssueDao.class,
+
+      // measures
+      MeasureDao.class,
+      MetricDao.class,
+      MeasureFilterDao.class,
+
+      // components
+      ComponentDao.class,
+      ComponentIndexDao.class,
+      ComponentLinkDao.class,
+      SnapshotDao.class,
+
+      EventDao.class,
+      ActivityDao.class,
+      AnalysisReportDao.class,
+      FileSourceDao.class,
+      FileDependencyDao.class);
+    addAll(CorePropertyDefinitions.all());
+    addAll(MigrationSteps.CLASSES);
+    addAll(DaoUtils.getDaoClasses());
+
+    return this;
+  }
+
+  private void addExtraRootComponents() {
+    if (this.extraRootComponents != null) {
+      for (Object extraRootComponent : this.extraRootComponents) {
+        add(extraRootComponent);
+      }
+    }
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java
new file mode 100644 (file)
index 0000000..ccedb2a
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.platform.platformlevel;
+
+import org.sonar.api.utils.Durations;
+import org.sonar.core.i18n.DefaultI18n;
+import org.sonar.core.i18n.RuleI18nManager;
+import org.sonar.core.platform.PluginLoader;
+import org.sonar.server.db.migrations.DatabaseMigrator;
+import org.sonar.server.db.migrations.PlatformDatabaseMigration;
+import org.sonar.server.db.migrations.PlatformDatabaseMigrationExecutorServiceImpl;
+import org.sonar.server.platform.DefaultServerUpgradeStatus;
+import org.sonar.server.platform.RailsAppsDeployer;
+import org.sonar.server.plugins.InstalledPluginReferentialFactory;
+import org.sonar.server.plugins.ServerExtensionInstaller;
+import org.sonar.server.plugins.ServerPluginExploder;
+import org.sonar.server.plugins.ServerPluginRepository;
+import org.sonar.server.ruby.PlatformRubyBridge;
+import org.sonar.server.ui.JRubyI18n;
+
+public class PlatformLevel2 extends PlatformLevel {
+  public PlatformLevel2(PlatformLevel parent) {
+    super("level2", parent);
+  }
+
+  @Override
+  public PlatformLevel configure() {
+    add(
+      DefaultServerUpgradeStatus.class,
+      DatabaseMigrator.class,
+
+      // depends on Ruby
+      PlatformRubyBridge.class,
+
+      // plugins
+      ServerPluginRepository.class,
+      ServerPluginExploder.class,
+      PluginLoader.class,
+      InstalledPluginReferentialFactory.class,
+      ServerExtensionInstaller.class,
+
+      // depends on plugins
+      RailsAppsDeployer.class,
+      JRubyI18n.class,
+      DefaultI18n.class,
+      RuleI18nManager.class,
+      Durations.class,
+
+      // DB migration
+      PlatformDatabaseMigrationExecutorServiceImpl.class,
+      PlatformDatabaseMigration.class);
+    return this;
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java
new file mode 100644 (file)
index 0000000..52ec628
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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.platform.platformlevel;
+
+import org.sonar.api.utils.UriReader;
+import org.sonar.core.util.DefaultHttpDownloader;
+import org.sonar.jpa.session.DatabaseSessionProvider;
+import org.sonar.jpa.session.DefaultDatabaseConnector;
+import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory;
+import org.sonar.server.platform.PersistentSettings;
+import org.sonar.server.platform.ServerIdGenerator;
+import org.sonar.server.startup.ServerMetadataPersister;
+
+public class PlatformLevel3 extends PlatformLevel {
+  public PlatformLevel3(PlatformLevel parent) {
+    super("level3", parent);
+  }
+
+  @Override
+  public PlatformLevel configure() {
+    add(
+      PersistentSettings.class,
+      DefaultDatabaseConnector.class,
+      ThreadLocalDatabaseSessionFactory.class,
+      new DatabaseSessionProvider(),
+      ServerMetadataPersister.class,
+      DefaultHttpDownloader.class,
+      UriReader.class,
+      ServerIdGenerator.class);
+    return this;
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
new file mode 100644 (file)
index 0000000..c20b517
--- /dev/null
@@ -0,0 +1,715 @@
+/*
+ * 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.platform.platformlevel;
+
+import java.util.List;
+
+import org.sonar.api.config.EmailSettings;
+import org.sonar.api.issue.action.Actions;
+import org.sonar.api.profiles.AnnotationProfileParser;
+import org.sonar.api.profiles.XMLProfileParser;
+import org.sonar.api.profiles.XMLProfileSerializer;
+import org.sonar.api.resources.Languages;
+import org.sonar.api.resources.ResourceTypes;
+import org.sonar.api.rules.AnnotationRuleParser;
+import org.sonar.api.rules.XMLRuleParser;
+import org.sonar.api.server.rule.RulesDefinitionXmlLoader;
+import org.sonar.core.component.SnapshotPerspectives;
+import org.sonar.core.computation.dbcleaner.DefaultPurgeTask;
+import org.sonar.core.computation.dbcleaner.IndexPurgeListener;
+import org.sonar.core.computation.dbcleaner.ProjectCleaner;
+import org.sonar.core.computation.dbcleaner.period.DefaultPeriodCleaner;
+import org.sonar.core.issue.IssueFilterSerializer;
+import org.sonar.core.issue.IssueUpdater;
+import org.sonar.core.issue.workflow.FunctionExecutor;
+import org.sonar.core.issue.workflow.IssueWorkflow;
+import org.sonar.core.metric.DefaultMetricFinder;
+import org.sonar.core.notification.DefaultNotificationManager;
+import org.sonar.core.permission.PermissionFacade;
+import org.sonar.core.qualitygate.db.ProjectQgateAssociationDao;
+import org.sonar.core.qualitygate.db.QualityGateConditionDao;
+import org.sonar.core.qualitygate.db.QualityGateDao;
+import org.sonar.core.resource.DefaultResourcePermissions;
+import org.sonar.core.test.TestPlanPerspectiveLoader;
+import org.sonar.core.test.TestablePerspectiveLoader;
+import org.sonar.core.timemachine.Periods;
+import org.sonar.core.user.DefaultUserFinder;
+import org.sonar.core.user.HibernateUserFinder;
+import org.sonar.jpa.dao.MeasuresDao;
+import org.sonar.server.activity.ActivityService;
+import org.sonar.server.activity.RubyQProfileActivityService;
+import org.sonar.server.activity.index.ActivityIndex;
+import org.sonar.server.activity.index.ActivityIndexDefinition;
+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.BatchIndex;
+import org.sonar.server.batch.BatchWs;
+import org.sonar.server.batch.GlobalAction;
+import org.sonar.server.batch.IssuesAction;
+import org.sonar.server.batch.ProjectAction;
+import org.sonar.server.batch.ProjectRepositoryLoader;
+import org.sonar.server.batch.UsersAction;
+import org.sonar.server.charts.ChartFactory;
+import org.sonar.server.component.ComponentCleanerService;
+import org.sonar.server.component.ComponentService;
+import org.sonar.server.component.DefaultComponentFinder;
+import org.sonar.server.component.DefaultRubyComponentService;
+import org.sonar.server.component.ws.ComponentsWs;
+import org.sonar.server.component.ws.EventsWs;
+import org.sonar.server.component.ws.ResourcesWs;
+import org.sonar.server.computation.ComputationThreadLauncher;
+import org.sonar.server.computation.ReportQueue;
+import org.sonar.server.computation.ws.ComputationWs;
+import org.sonar.server.computation.ws.HistoryAction;
+import org.sonar.server.computation.ws.IsQueueEmptyWs;
+import org.sonar.server.computation.ws.QueueAction;
+import org.sonar.server.computation.ws.SubmitReportAction;
+import org.sonar.server.config.ws.PropertiesWs;
+import org.sonar.server.dashboard.ws.DashboardsWs;
+import org.sonar.server.debt.DebtCharacteristicsXMLImporter;
+import org.sonar.server.debt.DebtModelBackup;
+import org.sonar.server.debt.DebtModelLookup;
+import org.sonar.server.debt.DebtModelOperations;
+import org.sonar.server.debt.DebtModelPluginRepository;
+import org.sonar.server.debt.DebtModelService;
+import org.sonar.server.debt.DebtModelXMLExporter;
+import org.sonar.server.debt.DebtRulesXMLImporter;
+import org.sonar.server.design.ws.DependenciesWs;
+import org.sonar.server.duplication.ws.DuplicationsJsonWriter;
+import org.sonar.server.duplication.ws.DuplicationsParser;
+import org.sonar.server.duplication.ws.DuplicationsWs;
+import org.sonar.server.es.IndexCreator;
+import org.sonar.server.es.IndexDefinitions;
+import org.sonar.server.issue.ActionService;
+import org.sonar.server.issue.AddTagsAction;
+import org.sonar.server.issue.AssignAction;
+import org.sonar.server.issue.CommentAction;
+import org.sonar.server.issue.InternalRubyIssueService;
+import org.sonar.server.issue.IssueBulkChangeService;
+import org.sonar.server.issue.IssueChangelogFormatter;
+import org.sonar.server.issue.IssueChangelogService;
+import org.sonar.server.issue.IssueCommentService;
+import org.sonar.server.issue.IssueQueryService;
+import org.sonar.server.issue.IssueService;
+import org.sonar.server.issue.PlanAction;
+import org.sonar.server.issue.RemoveTagsAction;
+import org.sonar.server.issue.ServerIssueStorage;
+import org.sonar.server.issue.SetSeverityAction;
+import org.sonar.server.issue.TransitionAction;
+import org.sonar.server.issue.actionplan.ActionPlanService;
+import org.sonar.server.issue.actionplan.ActionPlanWs;
+import org.sonar.server.issue.filter.IssueFilterService;
+import org.sonar.server.issue.filter.IssueFilterWriter;
+import org.sonar.server.issue.filter.IssueFilterWs;
+import org.sonar.server.issue.index.IssueAuthorizationIndexer;
+import org.sonar.server.issue.index.IssueIndexDefinition;
+import org.sonar.server.issue.index.IssueIndexer;
+import org.sonar.server.issue.notification.ChangesOnMyIssueNotificationDispatcher;
+import org.sonar.server.issue.notification.DoNotFixNotificationDispatcher;
+import org.sonar.server.issue.notification.IssueChangesEmailTemplate;
+import org.sonar.server.issue.notification.MyNewIssuesEmailTemplate;
+import org.sonar.server.issue.notification.MyNewIssuesNotificationDispatcher;
+import org.sonar.server.issue.notification.NewIssuesEmailTemplate;
+import org.sonar.server.issue.notification.NewIssuesNotificationDispatcher;
+import org.sonar.server.issue.notification.NewIssuesNotificationFactory;
+import org.sonar.server.issue.ws.ComponentTagsAction;
+import org.sonar.server.issue.ws.IssueActionsWriter;
+import org.sonar.server.issue.ws.IssuesWs;
+import org.sonar.server.issue.ws.SetTagsAction;
+import org.sonar.server.language.ws.LanguageWs;
+import org.sonar.server.measure.MeasureFilterEngine;
+import org.sonar.server.measure.MeasureFilterExecutor;
+import org.sonar.server.measure.MeasureFilterFactory;
+import org.sonar.server.measure.ws.ManualMeasuresWs;
+import org.sonar.server.measure.ws.MetricsWs;
+import org.sonar.server.measure.ws.TimeMachineWs;
+import org.sonar.server.notifications.NotificationCenter;
+import org.sonar.server.notifications.NotificationService;
+import org.sonar.server.permission.InternalPermissionService;
+import org.sonar.server.permission.InternalPermissionTemplateService;
+import org.sonar.server.permission.PermissionFinder;
+import org.sonar.server.permission.ws.PermissionsWs;
+import org.sonar.server.platform.BackendCleanup;
+import org.sonar.server.platform.ServerLifecycleNotifier;
+import org.sonar.server.platform.SettingsChangeNotifier;
+import org.sonar.server.platform.monitoring.DatabaseMonitor;
+import org.sonar.server.platform.monitoring.EsMonitor;
+import org.sonar.server.platform.monitoring.JvmPropertiesMonitor;
+import org.sonar.server.platform.monitoring.PluginsMonitor;
+import org.sonar.server.platform.monitoring.SonarQubeMonitor;
+import org.sonar.server.platform.monitoring.SystemMonitor;
+import org.sonar.server.platform.ws.InfoAction;
+import org.sonar.server.platform.ws.L10nWs;
+import org.sonar.server.platform.ws.MigrateDbSystemAction;
+import org.sonar.server.platform.ws.RestartAction;
+import org.sonar.server.platform.ws.ServerWs;
+import org.sonar.server.platform.ws.StatusAction;
+import org.sonar.server.platform.ws.SystemWs;
+import org.sonar.server.platform.ws.UpgradesAction;
+import org.sonar.server.plugins.PluginDownloader;
+import org.sonar.server.plugins.ServerExtensionInstaller;
+import org.sonar.server.plugins.UpdateCenterClient;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.server.plugins.ws.AvailableAction;
+import org.sonar.server.plugins.ws.CancelAllAction;
+import org.sonar.server.plugins.ws.InstallAction;
+import org.sonar.server.plugins.ws.InstalledAction;
+import org.sonar.server.plugins.ws.PendingAction;
+import org.sonar.server.plugins.ws.PluginUpdateAggregator;
+import org.sonar.server.plugins.ws.PluginWSCommons;
+import org.sonar.server.plugins.ws.PluginsWs;
+import org.sonar.server.plugins.ws.UninstallAction;
+import org.sonar.server.plugins.ws.UpdatesAction;
+import org.sonar.server.project.ws.GhostsAction;
+import org.sonar.server.project.ws.ProjectsWs;
+import org.sonar.server.project.ws.ProvisionedAction;
+import org.sonar.server.properties.ProjectSettingsFactory;
+import org.sonar.server.qualitygate.QgateProjectFinder;
+import org.sonar.server.qualitygate.QualityGates;
+import org.sonar.server.qualitygate.ws.CreateConditionAction;
+import org.sonar.server.qualitygate.ws.DeleteConditionAction;
+import org.sonar.server.qualitygate.ws.DeselectAction;
+import org.sonar.server.qualitygate.ws.DestroyAction;
+import org.sonar.server.qualitygate.ws.QGatesWs;
+import org.sonar.server.qualitygate.ws.SelectAction;
+import org.sonar.server.qualitygate.ws.SetAsDefaultAction;
+import org.sonar.server.qualitygate.ws.UnsetDefaultAction;
+import org.sonar.server.qualitygate.ws.UpdateConditionAction;
+import org.sonar.server.qualityprofile.BuiltInProfiles;
+import org.sonar.server.qualityprofile.QProfileBackuper;
+import org.sonar.server.qualityprofile.QProfileComparison;
+import org.sonar.server.qualityprofile.QProfileCopier;
+import org.sonar.server.qualityprofile.QProfileExporters;
+import org.sonar.server.qualityprofile.QProfileFactory;
+import org.sonar.server.qualityprofile.QProfileLoader;
+import org.sonar.server.qualityprofile.QProfileLookup;
+import org.sonar.server.qualityprofile.QProfileProjectLookup;
+import org.sonar.server.qualityprofile.QProfileProjectOperations;
+import org.sonar.server.qualityprofile.QProfileReset;
+import org.sonar.server.qualityprofile.QProfileService;
+import org.sonar.server.qualityprofile.QProfiles;
+import org.sonar.server.qualityprofile.RuleActivator;
+import org.sonar.server.qualityprofile.RuleActivatorContextFactory;
+import org.sonar.server.qualityprofile.ws.BackupAction;
+import org.sonar.server.qualityprofile.ws.BulkRuleActivationActions;
+import org.sonar.server.qualityprofile.ws.ChangeParentAction;
+import org.sonar.server.qualityprofile.ws.ChangelogAction;
+import org.sonar.server.qualityprofile.ws.CompareAction;
+import org.sonar.server.qualityprofile.ws.CopyAction;
+import org.sonar.server.qualityprofile.ws.CreateAction;
+import org.sonar.server.qualityprofile.ws.ExportAction;
+import org.sonar.server.qualityprofile.ws.ExportersAction;
+import org.sonar.server.qualityprofile.ws.ImportersAction;
+import org.sonar.server.qualityprofile.ws.InheritanceAction;
+import org.sonar.server.qualityprofile.ws.ProfilesWs;
+import org.sonar.server.qualityprofile.ws.ProjectAssociationActions;
+import org.sonar.server.qualityprofile.ws.ProjectsAction;
+import org.sonar.server.qualityprofile.ws.QProfilesWs;
+import org.sonar.server.qualityprofile.ws.RenameAction;
+import org.sonar.server.qualityprofile.ws.RestoreAction;
+import org.sonar.server.qualityprofile.ws.RestoreBuiltInAction;
+import org.sonar.server.qualityprofile.ws.RuleActivationActions;
+import org.sonar.server.qualityprofile.ws.SetDefaultAction;
+import org.sonar.server.rule.DefaultRuleFinder;
+import org.sonar.server.rule.DeprecatedRulesDefinitionLoader;
+import org.sonar.server.rule.RubyRuleService;
+import org.sonar.server.rule.RuleCreator;
+import org.sonar.server.rule.RuleDefinitionsLoader;
+import org.sonar.server.rule.RuleDeleter;
+import org.sonar.server.rule.RuleOperations;
+import org.sonar.server.rule.RuleRepositories;
+import org.sonar.server.rule.RuleService;
+import org.sonar.server.rule.RuleUpdater;
+import org.sonar.server.rule.ws.ActiveRuleCompleter;
+import org.sonar.server.rule.ws.RepositoriesAction;
+import org.sonar.server.rule.ws.RuleMapping;
+import org.sonar.server.rule.ws.RulesWs;
+import org.sonar.server.rule.ws.TagsAction;
+import org.sonar.server.source.HtmlSourceDecorator;
+import org.sonar.server.source.SourceService;
+import org.sonar.server.source.index.SourceLineIndex;
+import org.sonar.server.source.index.SourceLineIndexDefinition;
+import org.sonar.server.source.index.SourceLineIndexer;
+import org.sonar.server.source.ws.HashAction;
+import org.sonar.server.source.ws.IndexAction;
+import org.sonar.server.source.ws.LinesAction;
+import org.sonar.server.source.ws.RawAction;
+import org.sonar.server.source.ws.ScmAction;
+import org.sonar.server.source.ws.SourcesWs;
+import org.sonar.server.test.CoverageService;
+import org.sonar.server.test.index.TestIndex;
+import org.sonar.server.test.index.TestIndexDefinition;
+import org.sonar.server.test.index.TestIndexer;
+import org.sonar.server.test.ws.CoveredFilesAction;
+import org.sonar.server.test.ws.TestsWs;
+import org.sonar.server.text.MacroInterpreter;
+import org.sonar.server.text.RubyTextService;
+import org.sonar.server.ui.PageDecorations;
+import org.sonar.server.ui.Views;
+import org.sonar.server.ui.ws.ComponentNavigationAction;
+import org.sonar.server.ui.ws.GlobalNavigationAction;
+import org.sonar.server.ui.ws.NavigationWs;
+import org.sonar.server.ui.ws.SettingsNavigationAction;
+import org.sonar.server.updatecenter.ws.UpdateCenterWs;
+import org.sonar.server.user.DefaultUserService;
+import org.sonar.server.user.GroupMembershipFinder;
+import org.sonar.server.user.GroupMembershipService;
+import org.sonar.server.user.NewUserNotifier;
+import org.sonar.server.user.SecurityRealmFactory;
+import org.sonar.server.user.UserUpdater;
+import org.sonar.server.user.index.UserIndex;
+import org.sonar.server.user.index.UserIndexDefinition;
+import org.sonar.server.user.index.UserIndexer;
+import org.sonar.server.user.ws.CurrentAction;
+import org.sonar.server.user.ws.FavoritesWs;
+import org.sonar.server.user.ws.UserPropertiesWs;
+import org.sonar.server.user.ws.UsersWs;
+import org.sonar.server.util.BooleanTypeValidation;
+import org.sonar.server.util.FloatTypeValidation;
+import org.sonar.server.util.IntegerTypeValidation;
+import org.sonar.server.util.StringListTypeValidation;
+import org.sonar.server.util.StringTypeValidation;
+import org.sonar.server.util.TextTypeValidation;
+import org.sonar.server.util.TypeValidations;
+import org.sonar.server.view.index.ViewIndex;
+import org.sonar.server.view.index.ViewIndexDefinition;
+import org.sonar.server.view.index.ViewIndexer;
+import org.sonar.server.ws.ListingWs;
+import org.sonar.server.ws.WebServiceEngine;
+
+public class PlatformLevel4 extends PlatformLevel {
+
+  private final List<Object> level4AddedComponents;
+
+  public PlatformLevel4(PlatformLevel parent, List<Object> level4AddedComponents) {
+    super("level4", parent);
+    this.level4AddedComponents = level4AddedComponents;
+  }
+
+  @Override
+  public PlatformLevel configure() {
+    add(
+      PluginDownloader.class,
+      ChartFactory.class,
+      Views.class,
+      ResourceTypes.class,
+      SettingsChangeNotifier.class,
+      PageDecorations.class,
+      DefaultResourcePermissions.class,
+      Periods.class,
+      ServerWs.class,
+      BackendCleanup.class,
+      IndexDefinitions.class,
+      IndexCreator.class,
+
+      // Activity
+      ActivityService.class,
+      ActivityIndexDefinition.class,
+      ActivityIndexer.class,
+      ActivityIndex.class,
+
+      // batch
+      BatchIndex.class,
+      GlobalAction.class,
+      ProjectAction.class,
+      ProjectRepositoryLoader.class,
+      SubmitReportAction.class,
+      IssuesAction.class,
+      UsersAction.class,
+      BatchWs.class,
+
+      // Dashboard
+      DashboardsWs.class,
+      org.sonar.server.dashboard.ws.ShowAction.class,
+
+      // update center
+      UpdateCenterClient.class,
+      UpdateCenterMatrixFactory.class,
+      UpdateCenterWs.class,
+
+      // quality profile
+      XMLProfileParser.class,
+      XMLProfileSerializer.class,
+      AnnotationProfileParser.class,
+      QProfiles.class,
+      QProfileLookup.class,
+      QProfileProjectOperations.class,
+      QProfileProjectLookup.class,
+      QProfileComparison.class,
+      BuiltInProfiles.class,
+      RestoreBuiltInAction.class,
+      org.sonar.server.qualityprofile.ws.SearchAction.class,
+      SetDefaultAction.class,
+      ProjectsAction.class,
+      org.sonar.server.qualityprofile.ws.DeleteAction.class,
+      RenameAction.class,
+      CopyAction.class,
+      BackupAction.class,
+      RestoreAction.class,
+      CreateAction.class,
+      ImportersAction.class,
+      InheritanceAction.class,
+      ChangeParentAction.class,
+      ChangelogAction.class,
+      CompareAction.class,
+      ExportAction.class,
+      ExportersAction.class,
+      QProfilesWs.class,
+      ProfilesWs.class,
+      RuleActivationActions.class,
+      BulkRuleActivationActions.class,
+      ProjectAssociationActions.class,
+      RuleActivator.class,
+      QProfileLoader.class,
+      QProfileExporters.class,
+      QProfileService.class,
+      RuleActivatorContextFactory.class,
+      QProfileFactory.class,
+      QProfileCopier.class,
+      QProfileBackuper.class,
+      QProfileReset.class,
+      RubyQProfileActivityService.class,
+
+      // rule
+      AnnotationRuleParser.class,
+      XMLRuleParser.class,
+      DefaultRuleFinder.class,
+      RuleOperations.class,
+      RubyRuleService.class,
+      RuleRepositories.class,
+      DeprecatedRulesDefinitionLoader.class,
+      RuleDefinitionsLoader.class,
+      RulesDefinitionXmlLoader.class,
+      RuleService.class,
+      RuleUpdater.class,
+      RuleCreator.class,
+      RuleDeleter.class,
+      org.sonar.server.rule.ws.UpdateAction.class,
+      RulesWs.class,
+      org.sonar.server.rule.ws.SearchAction.class,
+      org.sonar.server.rule.ws.ShowAction.class,
+      org.sonar.server.rule.ws.CreateAction.class,
+      org.sonar.server.rule.ws.DeleteAction.class,
+      TagsAction.class,
+      RuleMapping.class,
+      ActiveRuleCompleter.class,
+      RepositoriesAction.class,
+      org.sonar.server.rule.ws.AppAction.class,
+
+      // languages
+      Languages.class,
+      LanguageWs.class,
+      org.sonar.server.language.ws.ListAction.class,
+
+      // activity
+      ActivitiesWs.class,
+      org.sonar.server.activity.ws.SearchAction.class,
+      ActivityMapping.class);
+
+    // measure
+    add(MeasuresDao.class, false);
+
+    add(MeasureFilterFactory.class,
+      MeasureFilterExecutor.class,
+      MeasureFilterEngine.class,
+      DefaultMetricFinder.class,
+      ServerLifecycleNotifier.class,
+      TimeMachineWs.class,
+      ManualMeasuresWs.class,
+      MetricsWs.class,
+
+      // quality gates
+      QualityGateDao.class,
+      QualityGateConditionDao.class,
+      QualityGates.class,
+      ProjectQgateAssociationDao.class,
+      QgateProjectFinder.class,
+
+      org.sonar.server.qualitygate.ws.ListAction.class,
+      org.sonar.server.qualitygate.ws.SearchAction.class,
+      org.sonar.server.qualitygate.ws.ShowAction.class,
+      org.sonar.server.qualitygate.ws.CreateAction.class,
+      org.sonar.server.qualitygate.ws.RenameAction.class,
+      org.sonar.server.qualitygate.ws.CopyAction.class,
+      DestroyAction.class,
+      SetAsDefaultAction.class,
+      UnsetDefaultAction.class,
+      SelectAction.class,
+      DeselectAction.class,
+      CreateConditionAction.class,
+      DeleteConditionAction.class,
+      UpdateConditionAction.class,
+      org.sonar.server.qualitygate.ws.AppAction.class,
+      QGatesWs.class,
+
+      // web services
+      WebServiceEngine.class,
+      ListingWs.class,
+
+      // localization
+      L10nWs.class,
+
+      // authentication
+      AuthenticationWs.class,
+
+      // users
+      SecurityRealmFactory.class,
+      HibernateUserFinder.class,
+      NewUserNotifier.class,
+      DefaultUserFinder.class,
+      DefaultUserService.class,
+      UsersWs.class,
+      org.sonar.server.user.ws.CreateAction.class,
+      org.sonar.server.user.ws.UpdateAction.class,
+      org.sonar.server.user.ws.DeactivateAction.class,
+      org.sonar.server.user.ws.ChangePasswordAction.class,
+      CurrentAction.class,
+      org.sonar.server.user.ws.SearchAction.class,
+      org.sonar.server.user.ws.GroupsAction.class,
+      org.sonar.server.issue.ws.AuthorsAction.class,
+      FavoritesWs.class,
+      UserPropertiesWs.class,
+      UserIndexDefinition.class,
+      UserIndexer.class,
+      UserIndex.class,
+      UserUpdater.class,
+
+      // groups
+      GroupMembershipService.class,
+      GroupMembershipFinder.class,
+
+      // permissions
+      PermissionFacade.class,
+      InternalPermissionService.class,
+      InternalPermissionTemplateService.class,
+      PermissionFinder.class,
+      PermissionsWs.class,
+
+      // components
+      DefaultComponentFinder.class,
+      DefaultRubyComponentService.class,
+      ComponentService.class,
+      ResourcesWs.class,
+      ComponentsWs.class,
+      ProjectsWs.class,
+      org.sonar.server.component.ws.AppAction.class,
+      org.sonar.server.component.ws.SearchAction.class,
+      EventsWs.class,
+      ComponentCleanerService.class,
+      ProvisionedAction.class,
+      GhostsAction.class,
+
+      // views
+      ViewIndexDefinition.class,
+      ViewIndexer.class,
+      ViewIndex.class,
+
+      // issues
+      IssueIndexDefinition.class,
+      IssueIndexer.class,
+      IssueAuthorizationIndexer.class,
+      ServerIssueStorage.class,
+      IssueUpdater.class,
+      FunctionExecutor.class,
+      IssueWorkflow.class,
+      IssueCommentService.class,
+      InternalRubyIssueService.class,
+      IssueChangelogService.class,
+      ActionService.class,
+      Actions.class,
+      IssueBulkChangeService.class,
+      IssueChangelogFormatter.class,
+      IssuesWs.class,
+      org.sonar.server.issue.ws.ShowAction.class,
+      org.sonar.server.issue.ws.SearchAction.class,
+      org.sonar.server.issue.ws.TagsAction.class,
+      SetTagsAction.class,
+      ComponentTagsAction.class,
+      IssueService.class,
+      IssueActionsWriter.class,
+      IssueQueryService.class,
+      NewIssuesEmailTemplate.class,
+      MyNewIssuesEmailTemplate.class,
+      IssueChangesEmailTemplate.class,
+      ChangesOnMyIssueNotificationDispatcher.class,
+      ChangesOnMyIssueNotificationDispatcher.newMetadata(),
+      NewIssuesNotificationDispatcher.class,
+      NewIssuesNotificationDispatcher.newMetadata(),
+      MyNewIssuesNotificationDispatcher.class,
+      MyNewIssuesNotificationDispatcher.newMetadata(),
+      DoNotFixNotificationDispatcher.class,
+      DoNotFixNotificationDispatcher.newMetadata(),
+      NewIssuesNotificationFactory.class,
+
+      // issue filters
+      IssueFilterService.class,
+      IssueFilterSerializer.class,
+      IssueFilterWs.class,
+      IssueFilterWriter.class,
+      org.sonar.server.issue.filter.AppAction.class,
+      org.sonar.server.issue.filter.ShowAction.class,
+      org.sonar.server.issue.filter.FavoritesAction.class,
+
+      // action plan
+      ActionPlanWs.class,
+      ActionPlanService.class,
+
+      // issues actions
+      AssignAction.class,
+      PlanAction.class,
+      SetSeverityAction.class,
+      CommentAction.class,
+      TransitionAction.class,
+      AddTagsAction.class,
+      RemoveTagsAction.class,
+
+      // technical debt
+      DebtModelService.class,
+      DebtModelOperations.class,
+      DebtModelLookup.class,
+      DebtModelBackup.class,
+      DebtModelPluginRepository.class,
+      DebtModelXMLExporter.class,
+      DebtRulesXMLImporter.class,
+      DebtCharacteristicsXMLImporter.class,
+
+      // source
+      HtmlSourceDecorator.class,
+      SourceService.class,
+      SourcesWs.class,
+      org.sonar.server.source.ws.ShowAction.class,
+      LinesAction.class,
+      HashAction.class,
+      RawAction.class,
+      IndexAction.class,
+      ScmAction.class,
+      SourceLineIndexDefinition.class,
+      SourceLineIndex.class,
+      SourceLineIndexer.class,
+
+      // Duplications
+      DuplicationsParser.class,
+      DuplicationsWs.class,
+      DuplicationsJsonWriter.class,
+      org.sonar.server.duplication.ws.ShowAction.class,
+
+      // text
+      MacroInterpreter.class,
+      RubyTextService.class,
+
+      // Notifications
+      EmailSettings.class,
+      NotificationService.class,
+      NotificationCenter.class,
+      DefaultNotificationManager.class,
+
+      // Tests
+      CoverageService.class,
+      TestsWs.class,
+      CoveredFilesAction.class,
+      org.sonar.server.test.ws.ListAction.class,
+      TestIndexDefinition.class,
+      TestIndex.class,
+      TestIndexer.class,
+
+      // Properties
+      PropertiesWs.class,
+
+      // graphs and perspective related classes
+      TestablePerspectiveLoader.class,
+      TestPlanPerspectiveLoader.class,
+      SnapshotPerspectives.class,
+
+      // Type validation
+      TypeValidations.class,
+      IntegerTypeValidation.class,
+      FloatTypeValidation.class,
+      BooleanTypeValidation.class,
+      TextTypeValidation.class,
+      StringTypeValidation.class,
+      StringListTypeValidation.class,
+
+      // Design
+      DependenciesWs.class,
+      org.sonar.server.design.ws.ShowAction.class,
+
+      // System
+      RestartAction.class,
+      InfoAction.class,
+      UpgradesAction.class,
+      MigrateDbSystemAction.class,
+      StatusAction.class,
+      SystemWs.class,
+      SystemMonitor.class,
+      SonarQubeMonitor.class,
+      EsMonitor.class,
+      PluginsMonitor.class,
+      JvmPropertiesMonitor.class,
+      DatabaseMonitor.class,
+
+      // Plugins WS
+      PluginWSCommons.class,
+      PluginUpdateAggregator.class,
+      InstalledAction.class,
+      AvailableAction.class,
+      UpdatesAction.class,
+      PendingAction.class,
+      InstallAction.class,
+      org.sonar.server.plugins.ws.UpdateAction.class,
+      UninstallAction.class,
+      CancelAllAction.class,
+      PluginsWs.class,
+
+      // Compute engine
+      ReportQueue.class,
+      ComputationThreadLauncher.class,
+      ComputationWs.class,
+      IsQueueEmptyWs.class,
+      QueueAction.class,
+      HistoryAction.class,
+      DefaultPeriodCleaner.class,
+      DefaultPurgeTask.class,
+      ProjectCleaner.class,
+      ProjectSettingsFactory.class,
+      IndexPurgeListener.class,
+
+      // UI
+      GlobalNavigationAction.class,
+      SettingsNavigationAction.class,
+      ComponentNavigationAction.class,
+      NavigationWs.class);
+
+    addAll(level4AddedComponents);
+
+    return this;
+  }
+
+  @Override
+  public PlatformLevel start() {
+    ServerExtensionInstaller extensionInstaller = getComponentByType(ServerExtensionInstaller.class);
+    extensionInstaller.installExtensions(getContainer());
+
+    super.start();
+
+    return this;
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelSafeMode.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelSafeMode.java
new file mode 100644 (file)
index 0000000..1fa8116
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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.platform.platformlevel;
+
+import org.sonar.jpa.session.DefaultDatabaseConnector;
+import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory;
+import org.sonar.server.platform.ws.MigrateDbSystemAction;
+import org.sonar.server.platform.ws.StatusAction;
+import org.sonar.server.platform.ws.SystemWs;
+import org.sonar.server.ws.ListingWs;
+import org.sonar.server.ws.WebServiceEngine;
+
+public class PlatformLevelSafeMode extends PlatformLevel {
+  public PlatformLevelSafeMode(PlatformLevel parent) {
+    super("Safemode", parent);
+  }
+
+  @Override
+  public PlatformLevel configure() {
+    add(
+      // DB access required by DatabaseSessionFilter wired into ROR
+      DefaultDatabaseConnector.class,
+      ThreadLocalDatabaseSessionFactory.class,
+
+      // Server WS
+      StatusAction.class,
+      MigrateDbSystemAction.class,
+      SystemWs.class,
+
+      // Listing WS
+      ListingWs.class,
+
+      // WS engine
+      WebServiceEngine.class);
+
+    return this;
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java
new file mode 100644 (file)
index 0000000..acfe928
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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.platform.platformlevel;
+
+import org.sonar.jpa.session.DatabaseSessionFactory;
+import org.sonar.server.computation.ReportQueueCleaner;
+import org.sonar.server.issue.filter.RegisterIssueFilters;
+import org.sonar.server.platform.ServerLifecycleNotifier;
+import org.sonar.server.qualitygate.RegisterQualityGates;
+import org.sonar.server.qualityprofile.RegisterQualityProfiles;
+import org.sonar.server.rule.RegisterRules;
+import org.sonar.server.search.IndexSynchronizer;
+import org.sonar.server.startup.CopyRequirementsFromCharacteristicsToRules;
+import org.sonar.server.startup.GeneratePluginIndex;
+import org.sonar.server.startup.JdbcDriverDeployer;
+import org.sonar.server.startup.LogServerId;
+import org.sonar.server.startup.RegisterDashboards;
+import org.sonar.server.startup.RegisterDebtModel;
+import org.sonar.server.startup.RegisterMetrics;
+import org.sonar.server.startup.RegisterNewMeasureFilters;
+import org.sonar.server.startup.RegisterPermissionTemplates;
+import org.sonar.server.startup.RegisterServletFilters;
+import org.sonar.server.startup.RenameDeprecatedPropertyKeys;
+import org.sonar.server.startup.RenameIssueWidgets;
+import org.sonar.server.user.DoPrivileged;
+import org.sonar.server.user.ThreadLocalUserSession;
+
+public class PlatformLevelStartup extends PlatformLevel {
+  public PlatformLevelStartup(PlatformLevel parent) {
+    super("startup tasks", parent);
+  }
+
+  @Override
+  public PlatformLevel configure() {
+    add(
+      IndexSynchronizer.class,
+      RegisterMetrics.class,
+      RegisterQualityGates.class,
+      RegisterRules.class,
+      RegisterQualityProfiles.class,
+      JdbcDriverDeployer.class,
+      RegisterDebtModel.class,
+      GeneratePluginIndex.class,
+      RegisterNewMeasureFilters.class,
+      RegisterDashboards.class,
+      RegisterPermissionTemplates.class,
+      RenameDeprecatedPropertyKeys.class,
+      LogServerId.class,
+      RegisterServletFilters.class,
+      CopyRequirementsFromCharacteristicsToRules.class,
+      ReportQueueCleaner.class,
+      RegisterIssueFilters.class,
+      RenameIssueWidgets.class);
+
+    return this;
+  }
+
+  @Override
+  public PlatformLevel start() {
+    DoPrivileged.execute(new DoPrivileged.Task(getComponentByType(ThreadLocalUserSession.class)) {
+      @Override
+      protected void doPrivileged() {
+        getComponentByType(IndexSynchronizer.class).executeDeprecated();
+        PlatformLevelStartup.super.start();
+        getComponentByType(IndexSynchronizer.class).execute();
+        getComponentByType(ServerLifecycleNotifier.class).notifyStart();
+      }
+    });
+
+    return this;
+  }
+
+  @Override
+  public PlatformLevel stop() {
+    super.stop();
+
+    getComponentByType(DatabaseSessionFactory.class).clear();
+
+    return this;
+  }
+}
index 49dc10b3687b98081fdf6686949005fc4fbfd62a..50e932f73278d4737758877ad6d91be1fb5a696c 100644 (file)
  */
 package org.sonar.core.platform;
 
-import com.google.common.collect.Iterables;
+import java.util.Collection;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
 import org.picocontainer.Characteristics;
 import org.picocontainer.ComponentAdapter;
 import org.picocontainer.DefaultPicoContainer;
@@ -30,11 +34,10 @@ import org.picocontainer.monitors.NullComponentMonitor;
 import org.sonar.api.BatchSide;
 import org.sonar.api.ServerSide;
 import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.api.utils.log.Profiler;
 
-import javax.annotation.Nullable;
-
-import java.util.Collection;
-import java.util.List;
+import com.google.common.collect.Iterables;
 
 @BatchSide
 @ServerSide
@@ -234,7 +237,15 @@ public class ComponentContainer {
   }
 
   public static MutablePicoContainer createPicoContainer() {
-    ReflectionLifecycleStrategy lifecycleStrategy = new ReflectionLifecycleStrategy(new NullComponentMonitor(), "start", "stop", "close");
+    ReflectionLifecycleStrategy lifecycleStrategy = new ReflectionLifecycleStrategy(new NullComponentMonitor(), "start", "stop", "close") {
+      @Override
+      public void start(Object component) {
+        Profiler profiler = Profiler.createIfTrace(Loggers.get(ComponentContainer.class));
+        profiler.start();
+        super.start(component);
+        profiler.stopTrace(component.getClass().getCanonicalName() + " started");
+      }
+    };
     return new DefaultPicoContainer(new OptInCaching(), lifecycleStrategy, null);
   }