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.server.startup;
021
022import com.google.common.collect.Lists;
023import com.google.common.collect.Maps;
024import org.sonar.api.database.DatabaseSession;
025import org.sonar.api.measures.CoreMetrics;
026import org.sonar.api.measures.Metric;
027import org.sonar.api.measures.Metrics;
028import org.sonar.api.profiles.Alert;
029import org.sonar.api.utils.Logs;
030import org.sonar.api.utils.TimeProfiler;
031import org.sonar.jpa.dao.MeasuresDao;
032import org.sonar.server.platform.ServerStartException;
033
034import javax.persistence.Query;
035import java.util.List;
036import java.util.Map;
037
038public class RegisterMetrics {
039
040  private final MeasuresDao measuresDao;
041  private final Metrics[] metricsRepositories;
042  private final DatabaseSession session;
043
044  public RegisterMetrics(DatabaseSession session, MeasuresDao measuresDao, Metrics[] metricsRepositories) {
045    this.session = session;
046    this.measuresDao = measuresDao;
047    this.metricsRepositories = metricsRepositories;
048  }
049
050  public void start() {
051    TimeProfiler profiler = new TimeProfiler().start("Load metrics");
052    measuresDao.disableAutomaticMetrics();
053
054    List<Metric> metricsToRegister = Lists.newArrayList();
055    metricsToRegister.addAll(CoreMetrics.getMetrics());
056
057    Map<String, Metrics> metricsByRepository = Maps.newHashMap();
058    if (metricsRepositories != null) {
059      for (Metrics metrics : metricsRepositories) {
060        checkMetrics(metricsByRepository, metrics);
061        metricsToRegister.addAll(metrics.getMetrics());
062      }
063    }
064    register(metricsToRegister);
065    cleanAlerts();
066    profiler.stop();
067  }
068
069  private void checkMetrics(Map<String, Metrics> metricsByRepository, Metrics metrics) {
070    for (Metric metric : metrics.getMetrics()) {
071      String metricKey = metric.getKey();
072      if (CoreMetrics.getMetrics().contains(metric)) {
073        throw new ServerStartException("The following metric is already defined in sonar: " + metricKey);
074      }
075      Metrics anotherRepository = metricsByRepository.get(metricKey);
076      if (anotherRepository != null) {
077        throw new ServerStartException("The metric '" + metricKey + "' is already defined in the extension: " + anotherRepository);
078      }
079      metricsByRepository.put(metricKey, metrics);
080    }
081  }
082
083  protected void cleanAlerts() {
084    Logs.INFO.info("cleaning alert thresholds...");
085    Query query = session.createQuery("delete from " + Alert.class.getSimpleName() + " a where NOT EXISTS(FROM Metric m WHERE m=a.metric))");
086    query.executeUpdate();
087
088    query = session.createQuery("delete from " + Alert.class.getSimpleName() + " a where NOT EXISTS(FROM Metric m WHERE m=a.metric and m.enabled=:enabled))");
089    query.setParameter("enabled", Boolean.TRUE);
090    query.executeUpdate();
091    session.commit();
092  }
093
094  protected void register(List<Metric> metrics) {
095    measuresDao.registerMetrics(metrics);
096  }
097}