001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2011 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.server.startup;
021    
022    import com.google.common.collect.Lists;
023    import com.google.common.collect.Maps;
024    import org.sonar.api.database.DatabaseSession;
025    import org.sonar.api.measures.CoreMetrics;
026    import org.sonar.api.measures.Metric;
027    import org.sonar.api.measures.Metrics;
028    import org.sonar.api.profiles.Alert;
029    import org.sonar.api.utils.Logs;
030    import org.sonar.api.utils.TimeProfiler;
031    import org.sonar.jpa.dao.MeasuresDao;
032    import org.sonar.server.platform.ServerStartException;
033    
034    import javax.persistence.Query;
035    import java.util.List;
036    import java.util.Map;
037    
038    public class RegisterMetrics {
039    
040      private MeasuresDao measuresDao;
041      private Metrics[] metricsRepositories = null;
042      private 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    }