001 /*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * SonarQube is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
019 */
020 package org.sonar.batch.scan;
021
022 import org.slf4j.Logger;
023 import org.slf4j.LoggerFactory;
024 import org.sonar.api.BatchComponent;
025 import org.sonar.api.batch.InstantiationStrategy;
026 import org.sonar.api.batch.bootstrap.ProjectDefinition;
027 import org.sonar.api.batch.rule.CheckFactory;
028 import org.sonar.api.platform.ComponentContainer;
029 import org.sonar.api.resources.Project;
030 import org.sonar.api.scan.filesystem.FileExclusions;
031 import org.sonar.batch.*;
032 import org.sonar.batch.bootstrap.BatchExtensionDictionnary;
033 import org.sonar.batch.bootstrap.ExtensionInstaller;
034 import org.sonar.batch.bootstrap.ExtensionMatcher;
035 import org.sonar.batch.bootstrap.ExtensionUtils;
036 import org.sonar.batch.components.TimeMachineConfiguration;
037 import org.sonar.batch.debt.*;
038 import org.sonar.batch.events.EventBus;
039 import org.sonar.batch.index.DefaultIndex;
040 import org.sonar.batch.index.ResourcePersister;
041 import org.sonar.batch.issue.IssuableFactory;
042 import org.sonar.batch.issue.IssueFilters;
043 import org.sonar.batch.issue.ModuleIssues;
044 import org.sonar.batch.issue.ignore.EnforceIssuesFilter;
045 import org.sonar.batch.issue.ignore.IgnoreIssuesFilter;
046 import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer;
047 import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer;
048 import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader;
049 import org.sonar.batch.issue.ignore.scanner.IssueExclusionsRegexpScanner;
050 import org.sonar.batch.language.LanguageDistributionDecorator;
051 import org.sonar.batch.phases.PhaseExecutor;
052 import org.sonar.batch.phases.PhasesTimeProfiler;
053 import org.sonar.batch.qualitygate.GenerateQualityGateEvents;
054 import org.sonar.batch.qualitygate.QualityGateProvider;
055 import org.sonar.batch.qualitygate.QualityGateVerifier;
056 import org.sonar.batch.rule.*;
057 import org.sonar.batch.scan.filesystem.*;
058 import org.sonar.batch.scan.report.JsonReport;
059 import org.sonar.batch.scan2.AnalyzerOptimizer;
060 import org.sonar.core.component.ScanPerspectives;
061 import org.sonar.core.measure.MeasurementFilters;
062
063 public class ModuleScanContainer extends ComponentContainer {
064 private static final Logger LOG = LoggerFactory.getLogger(ModuleScanContainer.class);
065 private final Project module;
066
067 public ModuleScanContainer(ProjectScanContainer parent, Project module) {
068 super(parent);
069 this.module = module;
070 }
071
072 @Override
073 protected void doBeforeStart() {
074 LOG.info("------------- Scan {}", module.getName());
075 addCoreComponents();
076 addExtensions();
077 }
078
079 private void addCoreComponents() {
080 ProjectDefinition moduleDefinition = getComponentByType(ProjectTree.class).getProjectDefinition(module);
081 add(
082 moduleDefinition,
083 module.getConfiguration(),
084 module,
085 ModuleSettings.class);
086
087 // hack to initialize commons-configuration before ExtensionProviders
088 getComponentByType(ModuleSettings.class);
089
090 add(
091 EventBus.class,
092 PhaseExecutor.class,
093 PhasesTimeProfiler.class,
094 PhaseExecutor.getPhaseClasses(),
095 moduleDefinition.getContainerExtensions(),
096
097 // file system
098 ModuleInputFileCache.class,
099 FileExclusions.class,
100 ExclusionFilters.class,
101 DeprecatedFileFilters.class,
102 InputFileBuilderFactory.class,
103 StatusDetectionFactory.class,
104 LanguageDetectionFactory.class,
105 PreviousFileHashLoader.class,
106 FileIndexer.class,
107 ComponentIndexer.class,
108 LanguageVerifier.class,
109 FileSystemLogger.class,
110 DefaultProjectClasspath.class,
111 DefaultModuleFileSystem.class,
112 ModuleFileSystemInitializer.class,
113 ProjectFileSystemAdapter.class,
114 QProfileVerifier.class,
115
116 AnalyzerOptimizer.class,
117
118 // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor)
119 getComponentByType(ResourcePersister.class).getSnapshot(module),
120
121 TimeMachineConfiguration.class,
122 DefaultSensorContext.class,
123 SensorContextAdaptor.class,
124 BatchExtensionDictionnary.class,
125 DefaultTimeMachine.class,
126 ViolationFilters.class,
127 IssueFilters.class,
128 MeasurementFilters.class,
129 ResourceFilters.class,
130
131 // quality gates
132 new QualityGateProvider(),
133 QualityGateVerifier.class,
134 GenerateQualityGateEvents.class,
135
136 // rules
137 ModuleQProfiles.class,
138 new ActiveRulesProvider(),
139 new RulesProfileProvider(),
140 QProfileSensor.class,
141 QProfileDecorator.class,
142 QProfileEventsDecorator.class,
143 CheckFactory.class,
144
145 // report
146 JsonReport.class,
147
148 // issues
149 IssuableFactory.class,
150 ModuleIssues.class,
151
152 // issue exclusions
153 IssueInclusionPatternInitializer.class,
154 IssueExclusionPatternInitializer.class,
155 IssueExclusionsRegexpScanner.class,
156 IssueExclusionsLoader.class,
157 EnforceIssuesFilter.class,
158 IgnoreIssuesFilter.class,
159
160 // language
161 LanguageDistributionDecorator.class,
162
163 // Debt
164 IssueChangelogDebtCalculator.class,
165 DebtDecorator.class,
166 NewDebtDecorator.class,
167 SqaleRatingDecorator.class,
168 SqaleRatingSettings.class,
169
170 ScanPerspectives.class);
171 }
172
173 private void addExtensions() {
174 ExtensionInstaller installer = getComponentByType(ExtensionInstaller.class);
175 installer.install(this, new ExtensionMatcher() {
176 public boolean accept(Object extension) {
177 if (ExtensionUtils.isType(extension, BatchComponent.class) && ExtensionUtils.isInstantiationStrategy(extension, InstantiationStrategy.PER_PROJECT)) {
178 // Special use-case: the extension point ProjectBuilder is used in a Maven environment to define some
179 // new sub-projects without pom.
180 // Example : C# plugin adds sub-projects at runtime, even if they are not defined in root pom.
181 return !ExtensionUtils.isMavenExtensionOnly(extension) || module.getPom() != null;
182 }
183 return false;
184 }
185 });
186 }
187
188 @Override
189 protected void doAfterStart() {
190 DefaultIndex index = getComponentByType(DefaultIndex.class);
191 index.setCurrentProject(module,
192 getComponentByType(ModuleIssues.class));
193
194 getComponentByType(PhaseExecutor.class).execute(module);
195 }
196
197 }