All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.maven.ProjectContextImpl Maven / Gradle / Ivy

/*
 * Sonar, open source software quality management tool.
 * Copyright (C) 2009 SonarSource SA
 * mailto:contact AT sonarsource DOT com
 *
 * Sonar is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * Sonar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Sonar; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
 */
package org.sonar.maven;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.commons.Language;
import org.sonar.commons.Languages;
import org.sonar.commons.Metric;
import org.sonar.commons.database.DatabaseSession;
import org.sonar.commons.resources.*;
import org.sonar.commons.rules.Rule;
import org.sonar.commons.rules.RuleFailure;
import org.sonar.commons.rules.RuleFailureLevel;
import org.sonar.commons.rules.RuleFailureParam;
import org.sonar.plugins.api.maven.Exclusions;
import org.sonar.plugins.api.maven.ProjectContext;
import org.sonar.plugins.api.maven.model.MavenPom;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class ProjectContextImpl implements ProjectContext {
  private static Logger logger = LoggerFactory.getLogger(ProjectContextImpl.class);

  private DatabaseSession session;

  private Map resourceToSnapshot;
  private Map resourceToModel;

  private Snapshot projectSnapshot;
  private Resource project;
  private Exclusions exclusions;
  private Set resourceKeysToExclude;
  private Languages languages;
  private MeasuresDao measuresDao;

  public ProjectContextImpl(DatabaseSession session, Exclusions exclusions, Languages languages) {
    this.resourceToSnapshot = new HashMap();
    this.resourceToModel = new HashMap();
    this.session = session;
    this.exclusions = exclusions;
    this.resourceKeysToExclude = new HashSet();
    this.languages = languages;
    this.measuresDao = new MeasuresDao(session);
  }

  protected Snapshot init(MavenPom pom) {
    if (projectSnapshot != null) {
      return projectSnapshot;
    }
    project = loadProject(pom);

    projectSnapshot = new Snapshot();
    projectSnapshot.setResource(project);
    projectSnapshot.setVersion(pom.getAnalysisVersion());
    projectSnapshot.setCreatedAt(pom.getAnalysisDate());
    projectSnapshot = (Snapshot) session.save(projectSnapshot);
    return projectSnapshot;
  }

  private Resource loadProject(MavenPom pom) {
    Resource result = session.getSingleResult(Resource.class, "key", pom.getKey(), "scope", Resource.SCOPE_PROJECT, "enabled", true);
    if (result == null) {
      result = new Resource();
      result.setScope(Resource.SCOPE_PROJECT);
      result.setKey(pom.getKey());
      result.setQualifier(pom.isRoot() ? Resource.QUALIFIER_PROJECT_TRUNK : Resource.QUALIFIER_PROJECT_BRANCH);
      result.setLanguageKey(pom.getLanguageKey());
    }

    result.setName(pom.getName());
    result.setDescription(pom.getDescription());
    result = (Resource) session.save(result);
    return result;
  }

  public void addMeasure(Metric metric, Double value) {
    addMeasure(projectSnapshot, new Measure(metric, value));
  }

  public void addMeasure(Metric metric, String value) {
    addMeasure(projectSnapshot, new Measure(metric, value));
  }

  public void addMeasure(Measure measure) {
    addMeasure(projectSnapshot, measure);
  }

  public void addMeasure(Resource resource, Metric metric, Double value) {
    addMeasure(resource, new Measure(metric, value));
  }

  public void addMeasure(Resource resource, Metric metric, String value) {
    addMeasure(resource, new Measure(metric, value));
  }

  public void addMeasure(Resource resource, Measure measure) {
    try {
      Snapshot snapshot = saveSnapshot(resource);
      addMeasure(snapshot, measure);
    } catch (ExcludedResourceException e) {
      // nothing to do, the resource is excluded
    }
  }

  public void addViolation(Resource resource, Rule rule, String message, RuleFailureLevel level, RuleFailureParam... params) {
    try {
      RuleFailure failure = new RuleFailure(rule, level);
      failure.setMessage(message);
      failure.setSnapshot(reattach(saveSnapshot(resource)));
      failure = (RuleFailure) session.save(failure);

      for (RuleFailureParam param : params) {
        if (param != null) {
          param.setRuleFailure(failure);
          param.setSnapshot(reattach(saveSnapshot(resource)));
          failure.getParameters().add(param);
          session.save(param);
        }
      }
    } catch (ExcludedResourceException e) {
      // nothing to do, the resource is excluded
    }
  }

  public void addSource(Resource resource, String source) {
    try {
      Snapshot snapshot = reattach(saveSnapshot(resource));
      session.save(new SnapshotSource(snapshot, source));

    } catch (ExcludedResourceException e) {
      // nothing to do, the resource is excluded
    }
  }

  private Measure addMeasure(Snapshot snapshot, Measure measure) {
    measure.setMetric(measuresDao.getMetric(measure.getMetric()));
    measure.setSnapshotId(snapshot.getId());
    MeasureData data = measure.getMeasureData();
    measure.setMeasureData(null);
    measure = (Measure) session.save(measure);

    if (data != null) {
      data.setMeasure(session.getEntity(Measure.class, measure.getId()));
      data.setSnapshotId(snapshot.getId());
      session.save(data);
      measure.setMeasureData(data);
    }

    return measure;
  }

  private Snapshot saveSnapshot(Resource resource) throws ExcludedResourceException {
    if (resource == null) {
      return null;
    }

    Language language = languages.get(resource.getLanguageKey());
    Snapshot parent = saveSnapshot(language.getParent(resource));
    Snapshot snapshot = resourceToSnapshot.get(resource);
    if (snapshot == null) {
      snapshot = new Snapshot();
      snapshot.setResource(reattach(saveResource(resource)));
      snapshot.setCreatedAt(projectSnapshot.getCreatedAt());
      Snapshot root = reattach(projectSnapshot);
      snapshot.setRoot(root);
      if (parent == null) {
        snapshot.setParent(root);
      } else {
        snapshot.setParent(reattach(parent));
      }
      snapshot = (Snapshot) session.save(snapshot);
      resourceToSnapshot.put(resource, snapshot);
    }
    return snapshot;
  }

  private Resource saveResource(Resource resource) throws ExcludedResourceException {
    Resource row = resourceToModel.get(resource);
    if (row == null) {
      checkExclusions(resource);

      String fullkey = getResourceKey(resource);
      row = session.getSingleResult(Resource.class,
          "scope", resource.getScope(), "key", fullkey, "rootId", project.getId(), "enabled", true);
      if (row == null) {
        row = new Resource(resource.getScope(), fullkey, resource.getQualifier(), project.getId(), resource.getName());
        row.setLanguageKey(resource.getLanguageKey());
        row = (Resource) session.save(row);
      }
      resourceToModel.put(resource, row);
    }
    return row;
  }

  public String getResourceKey(Resource resource) {
    return new StringBuilder(64).append(project.getKey()).append(':').append(resource.getKey()).toString();
  }

  private Resource reattach(Resource row) {
    return session.reattach(Resource.class, row.getId());
  }

  private Snapshot reattach(Snapshot row) {
    return session.reattach(Snapshot.class, row.getId());
  }

  private void checkExclusions(Resource resource) throws ExcludedResourceException {
    boolean match = resourceKeysToExclude.contains(resource.getKey());
    if (!match) {
      match = matchResourceWithExclusions(resource);
      if (match) {
        resourceKeysToExclude.add(resource.getKey());
        logger.info("Exclude {}", resource.getKey());

      }
    }
    if (match) {
      throw new ExcludedResourceException();
    }
  }

  private boolean matchResourceWithExclusions(Resource resource) {
    Language language = languages.get(resource.getLanguageKey());
    if (exclusions != null && language != null) {
      for (String pattern : exclusions.getWildcardPatterns()) {
        boolean match = language.matchExclusionPattern(resource, pattern);
        if (match) {
          return true;
        }
      }
    }
    return false;
  }

  static class ExcludedResourceException extends Exception {

  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy