Package org.sonar.server.qualityprofile

Source Code of org.sonar.server.qualityprofile.RegisterQualityProfiles

/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
package org.sonar.server.qualityprofile;

import com.google.common.base.Function;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.ServerComponent;
import org.sonar.api.profiles.ProfileDefinition;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.ActiveRuleParam;
import org.sonar.api.utils.TimeProfiler;
import org.sonar.api.utils.ValidationMessages;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.qualityprofile.db.QualityProfileDto;
import org.sonar.core.template.LoadedTemplateDto;
import org.sonar.server.db.DbClient;
import org.sonar.server.platform.PersistentSettings;

import javax.annotation.Nullable;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* Synchronize Quality profiles during server startup
*/
public class RegisterQualityProfiles implements ServerComponent {

  private static final Logger LOGGER = LoggerFactory.getLogger(RegisterQualityProfiles.class);
  private static final String DEFAULT_PROFILE_NAME = "Sonar way";

  private final PersistentSettings settings;
  private final List<ProfileDefinition> definitions;
  private final BuiltInProfiles builtInProfiles;
  private final DbClient dbClient;
  private final QProfileFactory profileFactory;
  private final RuleActivator ruleActivator;

  /**
   * To be kept when no ProfileDefinition are injected
   */
  public RegisterQualityProfiles(PersistentSettings settings, BuiltInProfiles builtInProfiles,
    DbClient dbClient, QProfileFactory profileFactory, RuleActivator ruleActivator) {
    this(settings, builtInProfiles, dbClient, profileFactory, ruleActivator, Collections.<ProfileDefinition>emptyList());
  }

  public RegisterQualityProfiles(PersistentSettings settings, BuiltInProfiles builtInProfiles,
    DbClient dbClient, QProfileFactory profileFactory, RuleActivator ruleActivator,
    List<ProfileDefinition> definitions) {
    this.settings = settings;
    this.builtInProfiles = builtInProfiles;
    this.dbClient = dbClient;
    this.profileFactory = profileFactory;
    this.ruleActivator = ruleActivator;
    this.definitions = definitions;
  }

  public void start() {
    TimeProfiler profiler = new TimeProfiler(LOGGER).start("Register Quality Profiles");

    DbSession session = dbClient.openSession(false);
    try {
      ListMultimap<String, RulesProfile> profilesByLanguage = profilesByLanguage();
      for (String language : profilesByLanguage.keySet()) {
        List<RulesProfile> defs = profilesByLanguage.get(language);
        verifyLanguage(language, defs);

        for (Map.Entry<String, Collection<RulesProfile>> entry : profilesByName(defs).entrySet()) {
          String name = entry.getKey();
          QProfileName profileName = new QProfileName(language, name);
          if (shouldRegister(profileName, session)) {
            register(profileName, entry.getValue(), session);
            session.commit();
          }
          builtInProfiles.put(language, name);
        }
        setDefault(language, defs, session);
        session.commit();
      }

    } finally {
      session.close();
      profiler.stop();
    }
  }

  private static void verifyLanguage(String language, List<RulesProfile> profiles) {
    if (profiles.isEmpty()) {
      LOGGER.warn("No Quality Profile defined for language: " + language);
    }

    Set<String> defaultProfileNames = defaultProfileNames(profiles);
    if (defaultProfileNames.size() > 1) {
      throw new IllegalStateException("Several Quality profiles are flagged as default for the language " + language + ": " + defaultProfileNames);
    }
  }

  private void register(QProfileName name, Collection<RulesProfile> profiles, DbSession session) {
    LOGGER.info("Register profile " + name);

    QualityProfileDto profileDto = dbClient.qualityProfileDao().getByNameAndLanguage(name.getName(), name.getLanguage(), session);
    if (profileDto != null) {
      profileFactory.delete(session, profileDto.getKey(), true);
    }
    profileFactory.create(session, name);

    for (RulesProfile profile : profiles) {
      for (org.sonar.api.rules.ActiveRule activeRule : profile.getActiveRules()) {
        RuleKey ruleKey = RuleKey.of(activeRule.getRepositoryKey(), activeRule.getRuleKey());
        RuleActivation activation = new RuleActivation(ruleKey);
        activation.setSeverity(activeRule.getSeverity() != null ? activeRule.getSeverity().name() : null);
        for (ActiveRuleParam param : activeRule.getActiveRuleParams()) {
          activation.setParameter(param.getKey(), param.getValue());
        }
        ruleActivator.activate(session, activation, name);
      }
    }

    LoadedTemplateDto template = new LoadedTemplateDto(templateKey(name), LoadedTemplateDto.QUALITY_PROFILE_TYPE);
    dbClient.loadedTemplateDao().insert(template, session);
  }

  private void setDefault(String language, List<RulesProfile> profileDefs, DbSession session) {
    String propertyKey = "sonar.profile." + language;
    boolean upToDate = false;
    String currentDefault = settings.getString(propertyKey);
    if (currentDefault != null) {
      // check validity
      QualityProfileDto profile = dbClient.qualityProfileDao().getByNameAndLanguage(currentDefault, language, session);
      if (profile != null) {
        upToDate = true;
      }
    }

    if (!upToDate) {
      String defaultProfileName = defaultProfileName(profileDefs);
      LOGGER.info("Set default " + language + " profile: " + defaultProfileName);
      settings.saveProperty(propertyKey, defaultProfileName);
    }
  }

  /**
   * @return profiles by language
   */
  private ListMultimap<String, RulesProfile> profilesByLanguage() {
    ListMultimap<String, RulesProfile> byLang = ArrayListMultimap.create();
    for (ProfileDefinition definition : definitions) {
      ValidationMessages validation = ValidationMessages.create();
      RulesProfile profile = definition.createProfile(validation);
      validation.log(LOGGER);
      if (profile != null && !validation.hasErrors()) {
        byLang.put(StringUtils.lowerCase(profile.getLanguage()), profile);
      }
    }
    return byLang;
  }

  private static Map<String, Collection<RulesProfile>> profilesByName(List<RulesProfile> profiles) {
    return Multimaps.index(profiles, new Function<RulesProfile, String>() {
      @Override
      public String apply(@Nullable RulesProfile profile) {
        return profile != null ? profile.getName() : null;
      }
    }).asMap();
  }

  private static String defaultProfileName(List<RulesProfile> profiles) {
    String defaultName = null;
    boolean hasSonarWay = false;

    for (RulesProfile profile : profiles) {
      if (profile.getDefaultProfile()) {
        defaultName = profile.getName();
      } else if (DEFAULT_PROFILE_NAME.equals(profile.getName())) {
        hasSonarWay = true;
      }
    }

    if (StringUtils.isBlank(defaultName) && !hasSonarWay && !profiles.isEmpty()) {
      defaultName = profiles.get(0).getName();
    }

    return StringUtils.defaultIfBlank(defaultName, DEFAULT_PROFILE_NAME);
  }

  private static Set<String> defaultProfileNames(Collection<RulesProfile> profiles) {
    Set<String> names = Sets.newTreeSet();
    for (RulesProfile profile : profiles) {
      if (profile.getDefaultProfile()) {
        names.add(profile.getName());
      }
    }
    return names;
  }

  private boolean shouldRegister(QProfileName key, DbSession session) {
    return dbClient.loadedTemplateDao()
      .countByTypeAndKey(LoadedTemplateDto.QUALITY_PROFILE_TYPE, templateKey(key), session) == 0;
  }

  static String templateKey(QProfileName key) {
    return StringUtils.lowerCase(key.getLanguage()) + ":" + key.getName();
  }
}
TOP

Related Classes of org.sonar.server.qualityprofile.RegisterQualityProfiles

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.