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 org.apache.commons.lang.StringUtils; 024 import org.slf4j.Logger; 025 import org.slf4j.LoggerFactory; 026 import org.sonar.api.database.DatabaseSession; 027 import org.sonar.api.profiles.ProfileDefinition; 028 import org.sonar.api.profiles.RulesProfile; 029 import org.sonar.api.rules.*; 030 import org.sonar.api.utils.TimeProfiler; 031 import org.sonar.api.utils.ValidationMessages; 032 import org.sonar.jpa.session.DatabaseSessionFactory; 033 034 import java.util.ArrayList; 035 import java.util.Arrays; 036 import java.util.List; 037 038 public final class RegisterProvidedProfiles { 039 040 private static final Logger LOGGER = LoggerFactory.getLogger(RegisterProvidedProfiles.class); 041 042 private DatabaseSessionFactory sessionFactory; 043 private List<ProfileDefinition> definitions = Lists.newArrayList(); 044 private RuleFinder ruleFinder; 045 046 public RegisterProvidedProfiles(RuleFinder ruleFinder, DatabaseSessionFactory sessionFactory,// NOSONAR the parameter registerRulesBefore is unused must be declared for execution order of tasks 047 RegisterRules registerRulesBefore, 048 ProfileDefinition[] definitions) { 049 this.ruleFinder = ruleFinder; 050 this.sessionFactory = sessionFactory; 051 this.definitions.addAll(Arrays.asList(definitions)); 052 } 053 054 public RegisterProvidedProfiles(RuleFinder ruleFinder, DatabaseSessionFactory sessionFactory,// NOSONAR the parameter registerRulesBefore is unused must be declared for execution order of tasks 055 RegisterRules registerRulesBefore) { 056 this.ruleFinder = ruleFinder; 057 this.sessionFactory = sessionFactory; 058 } 059 060 public void start() { 061 TimeProfiler profiler = new TimeProfiler().start("Load provided profiles"); 062 063 List<RulesProfile> profiles = createProfiles(); 064 DatabaseSession session = sessionFactory.getSession(); 065 cleanProvidedProfiles(profiles, session); 066 saveProvidedProfiles(profiles, session); 067 session.commit(); 068 profiler.stop(); 069 } 070 071 List<RulesProfile> createProfiles() { 072 List<RulesProfile> result = Lists.newArrayList(); 073 for (ProfileDefinition definition : definitions) { 074 ValidationMessages validation = ValidationMessages.create(); 075 RulesProfile profile = definition.createProfile(validation); 076 validation.log(LOGGER); 077 if (profile != null && !validation.hasErrors()) { 078 result.add(profile); 079 } 080 } 081 return result; 082 } 083 084 void cleanProvidedProfiles(List<RulesProfile> profiles, DatabaseSession session) { 085 TimeProfiler profiler = new TimeProfiler().start("Clean provided profiles"); 086 List<RulesProfile> existingProfiles = session.getResults(RulesProfile.class, "provided", true); 087 for (RulesProfile existingProfile : existingProfiles) { 088 boolean isDeprecated = true; 089 for (RulesProfile profile : profiles) { 090 if (StringUtils.equals(existingProfile.getName(), profile.getName()) && StringUtils.equals(existingProfile.getLanguage(), profile.getLanguage())) { 091 isDeprecated = false; 092 break; 093 } 094 } 095 if (isDeprecated) { 096 session.removeWithoutFlush(existingProfile); 097 } else { 098 for (ActiveRule activeRule : existingProfile.getActiveRules()) { 099 session.removeWithoutFlush(activeRule); 100 } 101 existingProfile.setActiveRules(new ArrayList<ActiveRule>()); 102 session.saveWithoutFlush(existingProfile); 103 } 104 } 105 profiler.stop(); 106 } 107 108 void saveProvidedProfiles(List<RulesProfile> profiles, DatabaseSession session) { 109 for (RulesProfile profile : profiles) { 110 TimeProfiler profiler = new TimeProfiler().start("Save profile " + profile); 111 RulesProfile persistedProfile = findOrCreate(profile.getName(), profile.getLanguage(), session); 112 113 for (ActiveRule activeRule : profile.getActiveRules()) { 114 Rule rule = getPersistedRule(activeRule); 115 ActiveRule persistedRule = persistedProfile.activateRule(rule, activeRule.getSeverity()); 116 for (RuleParam param : rule.getParams()) { 117 String value = StringUtils.defaultString(activeRule.getParameter(param.getKey()), param.getDefaultValue()); 118 if (value != null) { 119 persistedRule.setParameter(param.getKey(), value); 120 } 121 } 122 } 123 124 session.saveWithoutFlush(persistedProfile); 125 profiler.stop(); 126 } 127 128 } 129 130 Rule getPersistedRule(ActiveRule activeRule) { 131 Rule rule = activeRule.getRule(); 132 if (rule != null && rule.getId() == null) { 133 if (rule.getKey() != null) { 134 rule = ruleFinder.findByKey(rule.getRepositoryKey(), rule.getKey()); 135 136 } else if (rule.getConfigKey() != null) { 137 rule = ruleFinder.find(RuleQuery.create().withRepositoryKey(rule.getRepositoryKey()).withConfigKey(rule.getConfigKey())); 138 } 139 } 140 return rule; 141 } 142 143 private RulesProfile findOrCreate(String name, String language, DatabaseSession session) { 144 RulesProfile profile = session.getSingleResult(RulesProfile.class, "name", name, "language", language); 145 if (profile == null) { 146 profile = RulesProfile.create(name, language); 147 profile.setProvided(true); 148 profile.setDefaultProfile(false); 149 } 150 return profile; 151 } 152 153 }