001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2009 SonarSource SA
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;
021
022 import org.picocontainer.Characteristics;
023 import org.picocontainer.MutablePicoContainer;
024 import org.sonar.api.Extension;
025 import org.sonar.api.Plugin;
026 import org.sonar.api.Plugins;
027 import org.sonar.api.batch.BatchExtensionDictionnary;
028 import org.sonar.api.batch.SensorContext;
029 import org.sonar.api.database.DatabaseSession;
030 import org.sonar.api.database.daos.*;
031 import org.sonar.api.measures.CoreMetrics;
032 import org.sonar.api.measures.Metric;
033 import org.sonar.api.resources.Languages;
034 import org.sonar.api.resources.Project;
035 import org.sonar.api.rules.RulesManager;
036 import org.sonar.api.utils.IocContainer;
037 import org.sonar.batch.indexer.DefaultSonarIndex;
038
039 public class ProjectBatch {
040
041 private MutablePicoContainer globalContainer;
042 private MutablePicoContainer batchContainer;
043
044 public ProjectBatch(MutablePicoContainer container) {
045 this.globalContainer = container;
046 }
047
048 public void execute(DefaultSonarIndex index, Project project) {
049 try {
050 startChildContainer(index, project);
051 SensorContext sensorContext = batchContainer.getComponent(SensorContext.class);
052 for (Class<? extends CoreJob> clazz : CoreJobs.allJobs()) {
053 CoreJob job = getComponent(clazz);
054 job.execute(project, sensorContext);
055 commit();
056 }
057
058 } finally {
059 index.clear();
060 stop();
061 }
062 }
063
064 public void startChildContainer(DefaultSonarIndex index, Project project) {
065 batchContainer = globalContainer.makeChildContainer();
066 Plugins plugins = new Plugins();
067
068 batchContainer.as(Characteristics.CACHE).addComponent(project);
069 batchContainer.as(Characteristics.CACHE).addComponent(index.getBucket(project).getSnapshot());
070 batchContainer.as(Characteristics.CACHE).addComponent(project.getConfiguration());
071
072 batchContainer.as(Characteristics.CACHE).addComponent(plugins);
073 batchContainer.as(Characteristics.CACHE).addComponent(DaoFacade.class);
074 batchContainer.as(Characteristics.CACHE).addComponent(RulesDao.class);
075 batchContainer.as(Characteristics.CACHE).addComponent(MeasuresDao.class);
076 batchContainer.as(Characteristics.CACHE).addComponent(ProfilesDao.class);
077 batchContainer.as(Characteristics.CACHE).addComponent(AsyncMeasuresDao.class);
078 batchContainer.as(Characteristics.CACHE).addComponent(AsyncMeasuresService.class);
079 batchContainer.as(Characteristics.CACHE).addComponent(RulesManager.class);
080 batchContainer.as(Characteristics.CACHE).addComponent(DefaultSensorContext.class);
081 batchContainer.as(Characteristics.CACHE).addComponent(Languages.class);
082 batchContainer.as(Characteristics.CACHE).addComponent(BatchExtensionDictionnary.class);
083 batchContainer.as(Characteristics.CACHE).addComponent(DefaultTimeMachine.class);
084 batchContainer.as(Characteristics.CACHE).addComponent(ViolationsDao.class);
085 batchContainer.as(Characteristics.CACHE).addComponent(ViolationFilters.class);
086 batchContainer.as(Characteristics.CACHE).addComponent(ResourceFilters.class);
087 batchContainer.addAdapter(new ProfileProvider());
088 loadExtensions(batchContainer, plugins);
089 loadCoreComponents(batchContainer);
090 batchContainer.as(Characteristics.CACHE).addComponent(new IocContainer(batchContainer));
091 batchContainer.start();
092
093 // post-initializations
094 project.setLanguage(getComponent(Languages.class).get(project.getLanguageKey()));
095 index.selectProject(project, getComponent(ResourceFilters.class), getComponent(ViolationFilters.class), getComponent(MeasuresDao.class), getComponent(ViolationsDao.class));
096 }
097
098 private void loadExtensions(MutablePicoContainer container, Plugins plugins) {
099 for (Plugin plugin : plugins.getPlugins()) {
100 for (Class<? extends Extension> extensionClass : plugin.getExtensions()) {
101 container.as(Characteristics.CACHE).addComponent(extensionClass);
102 }
103 }
104 }
105
106 private void loadCoreComponents(MutablePicoContainer container) {
107 for (Class<?> clazz : CoreJobs.allJobs()) {
108 container.as(Characteristics.CACHE).addComponent(clazz);
109 }
110 for (Metric metric : CoreMetrics.getMetrics()) {
111 container.as(Characteristics.CACHE).addComponent(metric.getKey(), metric);
112 }
113 }
114
115 private void stop() {
116 if (batchContainer != null) {
117 commit();
118 batchContainer.stop();
119 globalContainer.removeChildContainer(batchContainer);
120 }
121 }
122
123 public void commit() {
124 getComponent(DatabaseSession.class).commit();
125 }
126
127 public <T> T getComponent(Class<T> clazz) {
128 if (batchContainer != null) {
129 return batchContainer.getComponent(clazz);
130 }
131 return globalContainer.getComponent(clazz);
132 }
133 }