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.plugins.core.sensors;
021
022import com.google.common.collect.Lists;
023import org.apache.commons.lang.StringUtils;
024import org.sonar.api.batch.*;
025import org.sonar.api.measures.CoreMetrics;
026import org.sonar.api.measures.Measure;
027import org.sonar.api.measures.Metric;
028import org.sonar.api.profiles.Alert;
029import org.sonar.api.profiles.RulesProfile;
030import org.sonar.api.resources.Project;
031import org.sonar.api.resources.Resource;
032import org.sonar.api.resources.ResourceUtils;
033
034import java.util.List;
035
036public 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}