001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2012 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * Sonar 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     * Sonar 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
017     * License along with Sonar; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019     */
020    package org.sonar.batch.bootstrap;
021    
022    import org.slf4j.Logger;
023    import org.slf4j.LoggerFactory;
024    import org.sonar.api.batch.BatchExtensionDictionnary;
025    import org.sonar.api.batch.bootstrap.ProjectDefinition;
026    import org.sonar.api.profiles.RulesProfile;
027    import org.sonar.api.resources.Language;
028    import org.sonar.api.resources.Languages;
029    import org.sonar.api.resources.Project;
030    import org.sonar.api.resources.ProjectFileSystem;
031    import org.sonar.api.rules.DefaultRulesManager;
032    import org.sonar.api.utils.IocContainer;
033    import org.sonar.api.utils.SonarException;
034    import org.sonar.batch.*;
035    import org.sonar.batch.components.TimeMachineConfiguration;
036    import org.sonar.batch.config.ProjectSettings;
037    import org.sonar.batch.events.EventBus;
038    import org.sonar.batch.index.DefaultIndex;
039    import org.sonar.batch.index.DefaultResourcePersister;
040    import org.sonar.batch.phases.Phases;
041    import org.sonar.batch.phases.PhasesTimeProfiler;
042    import org.sonar.core.qualitymodel.DefaultModelFinder;
043    import org.sonar.jpa.dao.DaoFacade;
044    import org.sonar.jpa.dao.ProfilesDao;
045    import org.sonar.jpa.dao.RulesDao;
046    
047    public class ProjectModule extends Module {
048      private static final Logger LOG = LoggerFactory.getLogger(ProjectModule.class);
049      private Project project;
050      private boolean dryRun;
051    
052      public ProjectModule(Project project, boolean dryRun) {
053        this.project = project;
054        this.dryRun = dryRun;
055      }
056    
057      @Override
058      protected void configure() {
059        logSettings();
060        addCoreComponents();
061        addProjectComponents();
062        addProjectPluginExtensions();
063      }
064    
065    
066      private void addProjectComponents() {
067        ProjectDefinition projectDefinition = getComponentByType(ProjectTree.class).getProjectDefinition(project);
068        addCoreSingleton(projectDefinition);
069        addCoreSingleton(project);
070        addCoreSingleton(project.getConfiguration());
071        addCoreSingleton(ProjectSettings.class);
072        addCoreSingleton(IocContainer.class);
073    
074        for (Object component : projectDefinition.getContainerExtensions()) {
075          addCoreSingleton(component);
076        }
077        addCoreSingleton(DefaultProjectClasspath.class);
078        addCoreSingleton(DefaultProjectFileSystem2.class);
079        addCoreSingleton(DaoFacade.class);
080        addCoreSingleton(RulesDao.class);
081    
082        if (!dryRun) {
083          // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor)
084          addCoreSingleton(getComponentByType(DefaultResourcePersister.class).getSnapshot(project));
085        }
086        addCoreSingleton(TimeMachineConfiguration.class);
087        addCoreSingleton(org.sonar.api.database.daos.MeasuresDao.class);
088        addCoreSingleton(ProfilesDao.class);
089        addCoreSingleton(DefaultRulesManager.class);
090        addCoreSingleton(DefaultSensorContext.class);
091        addCoreSingleton(Languages.class);
092        addCoreSingleton(BatchExtensionDictionnary.class);
093        addCoreSingleton(DefaultTimeMachine.class);
094        addCoreSingleton(ViolationFilters.class);
095        addCoreSingleton(ResourceFilters.class);
096        addCoreSingleton(DefaultModelFinder.class);
097        addCoreSingleton(DefaultProfileLoader.class);
098        addAdapter(new ProfileProvider());
099      }
100    
101      private void addCoreComponents() {
102        addCoreSingleton(EventBus.class);
103        addCoreSingleton(Phases.class);
104        addCoreSingleton(PhasesTimeProfiler.class);
105        for (Class clazz : Phases.getPhaseClasses(dryRun)) {
106          addCoreSingleton(clazz);
107        }
108      }
109    
110      private void addProjectPluginExtensions() {
111        addCoreSingleton(ProjectExtensionInstaller.class);
112        ProjectExtensionInstaller installer = getComponentByType(ProjectExtensionInstaller.class);
113        installer.install(this);
114      }
115    
116    
117      private void logSettings() {
118        // TODO move these logs in a dedicated component
119        LOG.info("-------------  Analyzing {}", project.getName());
120      }
121    
122      /**
123       * Analyze project
124       */
125      @Override
126      protected void doStart() {
127        Language language = getComponentByType(Languages.class).get(project.getLanguageKey());
128        if (language == null) {
129          throw new SonarException("Language with key '" + project.getLanguageKey() + "' not found");
130        }
131        project.setLanguage(language);
132    
133        DefaultIndex index = getComponentByType(DefaultIndex.class);
134        index.setCurrentProject(project,
135          getComponentByType(ResourceFilters.class),
136          getComponentByType(ViolationFilters.class),
137          getComponentByType(RulesProfile.class));
138    
139        // TODO See http://jira.codehaus.org/browse/SONAR-2126
140        // previously MavenProjectBuilder was responsible for creation of ProjectFileSystem
141        project.setFileSystem(getComponentByType(ProjectFileSystem.class));
142    
143        getComponentByType(Phases.class).execute(project);
144      }
145    }