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.bootstrapper;
021    
022    import com.google.common.collect.Lists;
023    import org.sonar.api.batch.bootstrap.ProjectReactor;
024    import org.sonar.batch.bootstrap.BootstrapModule;
025    import org.sonar.batch.bootstrap.Module;
026    import org.sonar.core.PicoUtils;
027    
028    import java.util.Arrays;
029    import java.util.List;
030    import java.util.Map;
031    
032    /**
033     * Entry point for batch bootstrappers.
034     *
035     * @since 2.14
036     */
037    public final class Batch {
038    
039      private LoggingConfiguration logging;
040      private List components;
041      private ProjectReactor projectReactor;
042    
043      private Batch(Builder builder) {
044        components = Lists.newArrayList();
045        components.addAll(builder.components);
046        components.add(builder.environment);
047        projectReactor = builder.projectReactor;
048        if (builder.isEnableLoggingConfiguration()) {
049          logging = LoggingConfiguration.create().setProperties((Map) projectReactor.getRoot().getProperties());
050        }
051      }
052    
053      public LoggingConfiguration getLoggingConfiguration() {
054        return logging;
055      }
056    
057      public Batch execute() {
058        configureLogging();
059        startBatch();
060        return this;
061      }
062    
063      private void configureLogging() {
064        if (logging != null) {
065          logging.configure();
066        }
067      }
068    
069      private void startBatch() {
070        Module bootstrapModule = new BootstrapModule(projectReactor, components.toArray(new Object[components.size()])).init();
071        try {
072          bootstrapModule.start();
073        } catch (RuntimeException e) {
074          PicoUtils.propagateStartupException(e);
075        } finally {
076          try {
077            bootstrapModule.stop();
078          } catch (Exception e) {
079            // never throw exceptions in a finally block
080          }
081        }
082      }
083    
084    
085      public static Builder builder() {
086        return new Builder();
087      }
088    
089      public static final class Builder {
090        private ProjectReactor projectReactor;
091        private EnvironmentInformation environment;
092        private List components = Lists.newArrayList();
093        private boolean enableLoggingConfiguration = true;
094    
095        private Builder() {
096        }
097    
098        public Builder setProjectReactor(ProjectReactor projectReactor) {
099          this.projectReactor = projectReactor;
100          return this;
101        }
102    
103        public Builder setEnvironment(EnvironmentInformation env) {
104          this.environment = env;
105          return this;
106        }
107    
108        public Builder setComponents(List l) {
109          this.components = l;
110          return this;
111        }
112    
113        public Builder addComponents(Object... components) {
114          this.components.addAll(Arrays.asList(components));
115          return this;
116        }
117    
118        public Builder addComponent(Object component) {
119          this.components.add(component);
120          return this;
121        }
122    
123        public boolean isEnableLoggingConfiguration() {
124          return enableLoggingConfiguration;
125        }
126    
127        /**
128         * Logback is configured by default. It can be disabled, but n this case the batch bootstrapper must provide its
129         * own implementation of SLF4J.
130         */
131        public Builder setEnableLoggingConfiguration(boolean b) {
132          this.enableLoggingConfiguration = b;
133          return this;
134        }
135    
136        public Batch build() {
137          if (projectReactor == null) {
138            throw new IllegalStateException("ProjectReactor is not set");
139          }
140          if (environment == null) {
141            throw new IllegalStateException("EnvironmentInfo is not set");
142          }
143          if (components == null) {
144            throw new IllegalStateException("Batch components are not set");
145          }
146          return new Batch(this);
147        }
148      }
149    }