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.apache.commons.configuration.PropertiesConfiguration;
023    import org.sonar.api.batch.bootstrap.ProjectReactor;
024    import org.sonar.api.config.EmailSettings;
025    import org.sonar.api.utils.HttpDownloader;
026    import org.sonar.api.utils.UriReader;
027    import org.sonar.batch.FakeMavenPluginExecutor;
028    import org.sonar.batch.MavenPluginExecutor;
029    import org.sonar.batch.RemoteServerMetadata;
030    import org.sonar.batch.ServerMetadata;
031    import org.sonar.batch.config.BatchDatabaseSettingsLoader;
032    import org.sonar.batch.config.BatchSettings;
033    import org.sonar.core.config.Logback;
034    import org.sonar.core.i18n.I18nManager;
035    import org.sonar.core.i18n.RuleI18nManager;
036    import org.sonar.core.persistence.DaoUtils;
037    import org.sonar.core.persistence.DatabaseVersion;
038    import org.sonar.core.persistence.MyBatis;
039    import org.sonar.jpa.session.DatabaseSessionProvider;
040    import org.sonar.jpa.session.DefaultDatabaseConnector;
041    import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory;
042    
043    import java.net.URLClassLoader;
044    
045    /**
046     * Level 1 components
047     */
048    public class BootstrapModule extends Module {
049    
050      private Object[] boostrapperComponents;
051      private ProjectReactor reactor;
052    
053      public BootstrapModule(ProjectReactor reactor, Object... boostrapperComponents) {
054        this.reactor = reactor;
055        this.boostrapperComponents = boostrapperComponents;
056      }
057    
058      @Override
059      protected void configure() {
060        addCoreSingleton(reactor);
061        addCoreSingleton(new PropertiesConfiguration());
062        addCoreSingleton(BatchSettings.class);
063        addCoreSingleton(DryRun.class);
064        addCoreSingleton(Logback.class);
065        addCoreSingleton(ServerMetadata.class);// registered here because used by BootstrapClassLoader
066        addCoreSingleton(TempDirectories.class);// registered here because used by BootstrapClassLoader
067        addCoreSingleton(HttpDownloader.class);// registered here because used by BootstrapClassLoader
068        addCoreSingleton(UriReader.class);// registered here because used by BootstrapClassLoader
069        addCoreSingleton(ArtifactDownloader.class);// registered here because used by BootstrapClassLoader
070        addCoreSingleton(JdbcDriverHolder.class);
071        addCoreSingleton(EmailSettings.class);
072        addCoreSingleton(I18nManager.class);
073        addCoreSingleton(RuleI18nManager.class);
074    
075        URLClassLoader bootstrapClassLoader = getComponentByType(JdbcDriverHolder.class).getClassLoader();
076        // set as the current context classloader for hibernate, else it does not find the JDBC driver.
077        Thread.currentThread().setContextClassLoader(bootstrapClassLoader);
078    
079        addCoreSingleton(RemoteServerMetadata.class);
080        // mybatis
081        addCoreSingleton(BatchDatabase.class);
082        addCoreSingleton(MyBatis.class);
083        addCoreSingleton(DatabaseVersion.class);
084        addCoreSingleton(DatabaseBatchCompatibility.class);
085        for (Class daoClass : DaoUtils.getDaoClasses()) {
086          addCoreSingleton(daoClass);
087        }
088    
089        // hibernate
090        addCoreSingleton(DefaultDatabaseConnector.class);
091        addCoreSingleton(ThreadLocalDatabaseSessionFactory.class);
092        addAdapter(new DatabaseSessionProvider());
093    
094        for (Object component : boostrapperComponents) {
095          addCoreSingleton(component);
096        }
097        if (!isMavenPluginExecutorRegistered()) {
098          addCoreSingleton(FakeMavenPluginExecutor.class);
099        }
100    
101        addCoreSingleton(BatchPluginRepository.class);
102        addCoreSingleton(BatchExtensionInstaller.class);
103        addCoreSingleton(BatchDatabaseSettingsLoader.class);
104      }
105    
106      boolean isMavenPluginExecutorRegistered() {
107        if (boostrapperComponents != null) {
108          for (Object component : boostrapperComponents) {
109            if (component instanceof Class && MavenPluginExecutor.class.isAssignableFrom((Class<?>) component)) {
110              return true;
111            }
112          }
113        }
114        return false;
115      }
116    
117      @Override
118      protected void doStart() {
119        boolean dryRun = getComponentByType(DryRun.class).isEnabled();
120        Module batchComponents = installChild(new BatchModule(dryRun));
121        batchComponents.start();
122      }
123    }