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