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