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.plugins.core.sensors;
021    
022    import com.google.common.collect.Lists;
023    import org.apache.commons.lang.StringUtils;
024    import org.sonar.api.batch.*;
025    import org.sonar.api.measures.CoreMetrics;
026    import org.sonar.api.measures.Measure;
027    import org.sonar.api.measures.Metric;
028    import org.sonar.api.profiles.Alert;
029    import org.sonar.api.profiles.RulesProfile;
030    import org.sonar.api.resources.Project;
031    import org.sonar.api.resources.Resource;
032    import org.sonar.api.resources.ResourceUtils;
033    
034    import java.util.List;
035    
036    public class CheckAlertThresholds implements Decorator {
037    
038      private final RulesProfile profile;
039    
040      public CheckAlertThresholds(RulesProfile profile) {
041        this.profile = profile;
042      }
043    
044      @DependedUpon
045      public Metric generatesAlertStatus() {
046        return CoreMetrics.ALERT_STATUS;
047      }
048    
049      @DependsUpon
050      public List<Metric> dependsUponMetrics() {
051        List<Metric> metrics = Lists.newLinkedList();
052        for (Alert alert : profile.getAlerts()) {
053          metrics.add(alert.getMetric());
054        }
055        return metrics;
056      }
057    
058    
059      public boolean shouldExecuteOnProject(Project project) {
060        return profile != null
061            && profile.getAlerts() != null
062            && profile.getAlerts().size() > 0
063            && ResourceUtils.isRootProject(project);
064      }
065    
066      public void decorate(final Resource resource, final DecoratorContext context) {
067        if (shouldDecorateResource(resource)) {
068          decorateResource(context);
069        }
070      }
071    
072      private void decorateResource(DecoratorContext context) {
073        Metric.Level globalLevel = Metric.Level.OK;
074        List<String> labels = Lists.newArrayList();
075    
076        for (final Alert alert : profile.getAlerts()) {
077          Measure measure = context.getMeasure(alert.getMetric());
078          if (measure != null) {
079            Metric.Level level = AlertUtils.getLevel(alert, measure);
080    
081            measure.setAlertStatus(level);
082            String text = getText(alert, level);
083            if (!StringUtils.isBlank(text)) {
084              measure.setAlertText(text);
085              labels.add(text);
086            }
087    
088            context.saveMeasure(measure);
089    
090            if (Metric.Level.WARN == level && globalLevel != Metric.Level.ERROR) {
091              globalLevel = Metric.Level.WARN;
092    
093            } else if (Metric.Level.ERROR == level) {
094              globalLevel = Metric.Level.ERROR;
095            }
096          }
097        }
098    
099        Measure globalMeasure = new Measure(CoreMetrics.ALERT_STATUS, globalLevel);
100        globalMeasure.setAlertStatus(globalLevel);
101        globalMeasure.setAlertText(StringUtils.join(labels, ", "));
102        context.saveMeasure(globalMeasure);
103      }
104    
105      private boolean shouldDecorateResource(final Resource resource) {
106        return ResourceUtils.isRootProject(resource);
107      }
108    
109      private String getText(Alert alert, Metric.Level level) {
110        if (level == Metric.Level.OK) {
111          return null;
112        }
113        return alert.getAlertLabel(level);
114      }
115    
116    
117      @Override
118      public String toString() {
119        return getClass().getSimpleName();
120      }
121    }