]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4326 Migrate registration of rules to MyBatis, synchronize tags
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Wed, 8 Jan 2014 17:36:25 +0000 (18:36 +0100)
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Fri, 10 Jan 2014 16:09:39 +0000 (17:09 +0100)
30 files changed:
sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
sonar-core/src/main/java/org/sonar/core/qualityprofile/db/ActiveRuleDao.java
sonar-core/src/main/java/org/sonar/core/qualityprofile/db/ActiveRuleMapper.java
sonar-core/src/main/java/org/sonar/core/rule/RuleDao.java
sonar-core/src/main/java/org/sonar/core/rule/RuleDto.java
sonar-core/src/main/java/org/sonar/core/rule/RuleMapper.java
sonar-core/src/main/java/org/sonar/core/rule/RuleTagDto.java
sonar-core/src/main/java/org/sonar/core/rule/RuleTagType.java [new file with mode: 0644]
sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/ActiveRuleMapper.xml
sonar-core/src/main/resources/org/sonar/core/rule/RuleMapper.xml
sonar-plugin-api/src/main/java/org/sonar/api/rules/Rule.java
sonar-server/src/main/java/org/sonar/server/startup/RegisterRules.java
sonar-server/src/test/java/org/sonar/server/startup/RegisterRulesTest.java
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/disableDeprecatedActiveRuleParameters-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/disableDeprecatedActiveRules-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/disableDeprecatedRules-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/disableUserRulesIfParentIsDisabled-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/doNotDisableUserRulesIfParentIsEnabled-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/notUpdateAlreadyDisabledRule-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/reactivateDisabledRules-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/shouldNotDisableManualRules-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_disable_deprecated_repositories-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_reactivate_disabled_template_rules-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_save_new_repositories-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_store_bundle_name_and_description_in_database-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_update_template_rule_language-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_update_template_rule_language.xml
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/updadeRuleFields-result.xml [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/updadeRuleFields.xml
sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/updateRuleParameters-result.xml [new file with mode: 0644]

index f5cf9a16a6dd5a74860938aa59719cb0c319bbf7..70cee77251c57784d902885e95fd6c757501a33f 100644 (file)
@@ -63,6 +63,7 @@ import org.sonar.core.resource.*;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.core.rule.RuleMapper;
 import org.sonar.core.rule.RuleParamDto;
+import org.sonar.core.rule.RuleTagDto;
 import org.sonar.core.source.jdbc.SnapshotDataDto;
 import org.sonar.core.source.jdbc.SnapshotDataMapper;
 import org.sonar.core.source.jdbc.SnapshotSourceMapper;
index cb7bea9b8cccaa97e60977c0904588f9271436a9..11612a54a2e8bf2986314339c53684416750a467 100644 (file)
@@ -232,6 +232,10 @@ public class ActiveRuleDao implements ServerComponent {
     }
   }
 
+  public void deleteParametersWithParamId(Integer id, SqlSession session) {
+    session.getMapper(ActiveRuleMapper.class).deleteParametersWithParamId(id);
+  }
+
   public ActiveRuleParamDto selectParamById(Integer activeRuleParamId) {
     SqlSession session = mybatis.openSession();
     try {
@@ -301,5 +305,4 @@ public class ActiveRuleDao implements ServerComponent {
   public List<ActiveRuleParamDto> selectAllParams(SqlSession session) {
     return session.getMapper(ActiveRuleMapper.class).selectAllParams();
   }
-
 }
index 40817bac9dfd4f723c3d96e5dbec7ec7d9b87501..b473d6b91e173114c3342cb5079a5d77d62bedf2 100644 (file)
@@ -54,6 +54,8 @@ public interface ActiveRuleMapper {
 
   void deleteParameter(Integer activeRuleParamId);
 
+  void deleteParametersWithParamId(Integer id);
+
   @CheckForNull
   ActiveRuleParamDto selectParamById(Integer activeRuleParamId);
 
@@ -64,4 +66,5 @@ public interface ActiveRuleMapper {
 
   List<ActiveRuleParamDto> selectAllParams();
 
+
 }
index a941792ba1151d6af60c8f055ebc629d3d209dc1..cc220f0a9bf1d038e3682ce6f1e3417af13d3c1d 100644 (file)
@@ -116,12 +116,16 @@ public class RuleDao implements BatchComponent, ServerComponent {
   public List<RuleParamDto> selectParameters() {
     SqlSession session = mybatis.openSession();
     try {
-      return getMapper(session).selectAllParams();
+      return selectParameters(session);
     } finally {
       MyBatis.closeQuietly(session);
     }
   }
 
+  public List<RuleParamDto> selectParameters(SqlSession session) {
+    return getMapper(session).selectAllParams();
+  }
+
   public List<RuleParamDto> selectParameters(Integer id) {
     SqlSession session = mybatis.openSession();
     try {
@@ -176,12 +180,23 @@ public class RuleDao implements BatchComponent, ServerComponent {
     return getMapper(session).selectAllTags();
   }
 
-  public List<RuleTagDto> selectTags() {
-    SqlSession session = mybatis.openSession();
-    try {
-      return selectTags(session);
-    } finally {
-      MyBatis.closeQuietly(session);
-    }
+  public void insert(RuleTagDto newTag, SqlSession session) {
+    getMapper(session).insertTag(newTag);
+  }
+
+  public void deleteTags(List<RuleTagDto> tagsToDelete, SqlSession session) {
+    // TODO
+  }
+
+  public void insertTags(List<RuleTagDto> tagsToInsert, SqlSession session) {
+    // TODO
+  }
+
+  public void deleteParam(RuleParamDto persistedParam, SqlSession sqlSession) {
+    getMapper(sqlSession).deleteParameter(persistedParam.getId());
+  }
+
+  public void deleteTag(RuleTagDto tagToDelete, SqlSession session) {
+    getMapper(session).deleteTag(tagToDelete.getId().intValue());
   }
 }
index 35065011f6e847549d358b991032c4dea0cb64f1..39e565539d3511026a03218e0d69f614d6ec1350 100644 (file)
  */
 package org.sonar.core.rule;
 
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.sonar.api.rules.Rule;
+
 import org.sonar.check.Cardinality;
 
 import java.util.Date;
@@ -194,4 +200,44 @@ public final class RuleDto {
     this.noteUpdatedAt = noteUpdatedAt;
     return this;
   }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (!(obj instanceof RuleDto)) {
+      return false;
+    }
+    if (this == obj) {
+      return true;
+    }
+    RuleDto other = (RuleDto) obj;
+    return new EqualsBuilder()
+      .append(repositoryKey, other.getRepositoryKey())
+      .append(ruleKey, other.getRuleKey())
+      .isEquals();
+  }
+
+  @Override
+  public int hashCode() {
+    return new HashCodeBuilder(17, 37)
+      .append(repositoryKey)
+      .append(ruleKey)
+      .toHashCode();
+  }
+
+  @Override
+  public String toString() {
+    // Note that ReflectionToStringBuilder will not work here - see SONAR-3077
+    return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+      .append("id", id)
+      .append("name", name)
+      .append("key", ruleKey)
+      .append("configKey", configKey)
+      .append("plugin", repositoryKey)
+      .append("severity", getSeverity())
+      .append("cardinality", cardinality)
+      .append("status", status)
+      .append("language", language)
+      .append("parentId", parentId)
+      .toString();
+  }
 }
index 3223d8db5af60f4c04301483b89f963af1d300de..94a67bc87610e1a23fd0236589c7d01691a75626 100644 (file)
@@ -48,5 +48,11 @@ public interface RuleMapper {
 
   void updateParameter(RuleParamDto param);
 
+  void deleteParameter(Integer paramId);
+
   List<RuleTagDto> selectAllTags();
+
+  void insertTag(RuleTagDto newTag);
+
+  void deleteTag(Integer tagId);
 }
index 2521f8a1225146b449d34674ab628da79a0f9393..9ded402613dad3a5997c70f03c06c7b37eab6b40 100644 (file)
@@ -53,12 +53,12 @@ public class RuleTagDto {
     return this;
   }
 
-  public String getType() {
-    return type;
+  public RuleTagType getType() {
+    return RuleTagType.valueOf(type);
   }
 
-  public RuleTagDto setType(String type) {
-    this.type = type;
+  public RuleTagDto setType(RuleTagType type) {
+    this.type = type.toString();
     return this;
   }
 }
diff --git a/sonar-core/src/main/java/org/sonar/core/rule/RuleTagType.java b/sonar-core/src/main/java/org/sonar/core/rule/RuleTagType.java
new file mode 100644 (file)
index 0000000..28fddfa
--- /dev/null
@@ -0,0 +1,6 @@
+package org.sonar.core.rule;
+
+public enum RuleTagType {
+
+  SYSTEM, ADMIN;
+}
index 949da6e786ec80251664fbe59a104005aa3940be..0d30bc0e49c739eef795e1b7de4d4735b06272bb 100644 (file)
     DELETE FROM active_rule_parameters WHERE active_rule_id=#{id}
   </update>
 
+  <update id="deleteParametersWithParamId" parameterType="Integer">
+    DELETE FROM active_rule_parameters WHERE rules_parameter_id=#{id}
+  </update>
+
   <update id="deleteParameter" parameterType="Integer">
     DELETE FROM active_rule_parameters WHERE id=#{id}
   </update>
index c1d76bdc2c6c53b0c35ad36ba6c50426461dbc72..8cff4b1c4effd1ffd499835254593dca175b8009 100644 (file)
     </where>
   </select>
 
+  <delete id="deleteParameter" parameterType="Integer">
+    delete from rules_parameters where id=#{id}
+  </delete>
+
   <insert id="insertParameter" parameterType="RuleParam" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
     INSERT INTO rules_parameters (rule_id, name, param_type, default_value, description)
     VALUES (#{ruleId}, #{name}, #{type}, #{defaultValue}, #{description})
     FROM rule_tags
   </select>
 
+  <insert id="insertTag" parameterType="RuleTag" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
+    INSERT INTO rule_tags (rule_id, tag, tag_type)
+    VALUES (#{ruleId}, #{tag}, #{type})
+  </insert>
+
+  <update id="deleteTag" parameterType="Integer">
+    DELETE FROM rule_tags WHERE id=#{tagId}
+  </update>
+
 </mapper>
 
index 5fb9950a92bb7d2982f9b38ade7862e9d0d3921f..8e52a54cf98afc7e63369fb94178018ab0f7e627 100644 (file)
@@ -20,6 +20,8 @@
 
 package org.sonar.api.rules;
 
+import com.google.common.collect.Sets;
+
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableSet;
 import org.apache.commons.lang.StringUtils;
@@ -280,12 +282,18 @@ public final class Rule {
     return parameter;
   }
 
+  /**
+   * @since 4.2
+   */
   public Collection<String> getTags() {
     return tags;
   }
 
+  /**
+   * @since 4.2
+   */
   public Rule setTags(String... tags) {
-    Set<String> newTags = new HashSet<String>();
+    Set<String> newTags = Sets.newTreeSet();
     newTags.addAll(Arrays.asList(tags));
     this.tags = Collections.unmodifiableSet(newTags);
     return this;
index 523ac4cba9c39786adea13ba72a482aa02ade096..f65306607beb3e526c8d895d9b75f48b18694879 100644 (file)
@@ -25,19 +25,22 @@ import com.google.common.base.Predicate;
 import com.google.common.base.Strings;
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
 import com.google.common.collect.Multimap;
 import org.apache.commons.lang.StringUtils;
+import org.apache.ibatis.session.SqlSession;
+import org.elasticsearch.common.collect.Sets;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.rules.ActiveRuleParam;
 import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.RuleParam;
 import org.sonar.api.rules.RuleRepository;
 import org.sonar.api.utils.SonarException;
 import org.sonar.api.utils.TimeProfiler;
 import org.sonar.core.i18n.RuleI18nManager;
-import org.sonar.jpa.session.DatabaseSessionFactory;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.qualityprofile.db.ActiveRuleDao;
+import org.sonar.core.rule.*;
 import org.sonar.server.configuration.ProfilesManager;
 import org.sonar.server.rule.RuleRegistry;
 
@@ -49,51 +52,59 @@ import static com.google.common.collect.Maps.newHashMap;
 public final class RegisterRules {
 
   private static final Logger LOG = LoggerFactory.getLogger(RegisterRules.class);
-  private final DatabaseSessionFactory sessionFactory;
   private final ProfilesManager profilesManager;
   private final List<RuleRepository> repositories;
   private final RuleI18nManager ruleI18nManager;
   private final RuleRegistry ruleRegistry;
+  private final MyBatis myBatis;
+  private final RuleDao ruleDao;
+  private final ActiveRuleDao activeRuleDao;
+  private SqlSession sqlSession;
 
-  private DatabaseSession session;
-
-  public RegisterRules(DatabaseSessionFactory sessionFactory, RuleRepository[] repos, RuleI18nManager ruleI18nManager, ProfilesManager profilesManager, RuleRegistry ruleRegistry) {
-    this.sessionFactory = sessionFactory;
+  public RegisterRules(RuleRepository[] repos, RuleI18nManager ruleI18nManager, ProfilesManager profilesManager, RuleRegistry ruleRegistry,
+    MyBatis myBatis, RuleDao ruleDao, ActiveRuleDao activeRuleDao) {
     this.profilesManager = profilesManager;
     this.repositories = newArrayList(repos);
     this.ruleI18nManager = ruleI18nManager;
     this.ruleRegistry = ruleRegistry;
+    this.myBatis = myBatis;
+    this.ruleDao = ruleDao;
+    this.activeRuleDao = activeRuleDao;
   }
 
-  public RegisterRules(DatabaseSessionFactory sessionFactory, RuleI18nManager ruleI18nManager, ProfilesManager profilesManager, RuleRegistry ruleRegistry) {
-    this(sessionFactory, new RuleRepository[0], ruleI18nManager, profilesManager, ruleRegistry);
+  public RegisterRules(RuleI18nManager ruleI18nManager, ProfilesManager profilesManager, RuleRegistry ruleRegistry, MyBatis myBatis,
+    RuleDao ruleDao, ActiveRuleDao activeRuleDao) {
+    this(new RuleRepository[0], ruleI18nManager, profilesManager, ruleRegistry, myBatis, ruleDao, activeRuleDao);
   }
 
   public void start() {
-    session = sessionFactory.getSession();
-    RulesByRepository existingRules = new RulesByRepository(findAllRules());
+    sqlSession = myBatis.openSession();
+
+    RulesByRepository existingRules = new RulesByRepository(
+        findAllRules(), ruleDao.selectParameters(sqlSession), ruleDao.selectTags(sqlSession));
 
-    List<Rule> registeredRules = registerRules(existingRules);
+    try {
+      List<RuleDto> registeredRules = registerRules(existingRules);
 
-    LOG.info("Removing deprecated rules");
-    disableDeprecatedRules(existingRules, registeredRules);
-    disableDeprecatedRepositories(existingRules);
+      LOG.info("Removing deprecated rules");
+      disableDeprecatedRules(existingRules, registeredRules);
+      disableDeprecatedRepositories(existingRules);
 
-    session.commit();
+      sqlSession.commit();
 
-    ruleRegistry.bulkRegisterRules();
+      ruleRegistry.bulkRegisterRules();
+    } finally {
+      sqlSession.close();
+    }
   }
 
-  private List<Rule> findAllRules() {
-    // the hardcoded repository "manual" is used for manual violations
-    return session.createQuery("from " + Rule.class.getSimpleName() + " r WHERE r.pluginName<>:repository")
-      .setParameter("repository", "manual")
-      .getResultList();
+  private List<RuleDto> findAllRules() {
+    return ruleDao.selectNonManual();
   }
 
-  private List<Rule> registerRules(RulesByRepository existingRules) {
+  private List<RuleDto> registerRules(RulesByRepository existingRules) {
     TimeProfiler profiler = new TimeProfiler();
-    List<Rule> registeredRules = newArrayList();
+    List<RuleDto> registeredRules = newArrayList();
     for (RuleRepository repository : repositories) {
       profiler.start("Register rules [" + repository.getKey() + "/" + StringUtils.defaultString(repository.getLanguage(), "-") + "]");
       registeredRules.addAll(registerRepositoryRules(repository, existingRules));
@@ -104,22 +115,25 @@ public final class RegisterRules {
     return registeredRules;
   }
 
-  private List<Rule> registerRepositoryRules(RuleRepository repository, RulesByRepository existingRules) {
-    List<Rule> registeredRules = newArrayList();
+  private List<RuleDto> registerRepositoryRules(RuleRepository repository, RulesByRepository existingRules) {
+    List<RuleDto> registeredRules = newArrayList();
     Map<String, Rule> ruleByKey = newHashMap();
+
     for (Rule rule : repository.createRules()) {
       updateRuleFromRepositoryInfo(rule, repository);
       validateRule(rule, repository.getKey());
       ruleByKey.put(rule.getKey(), rule);
-      registeredRules.add(rule);
+      registeredRules.add(dtoFrom(rule));
     }
     LOG.debug(ruleByKey.size() + " rules");
 
-    for (Rule persistedRule : existingRules.get(repository.getKey())) {
-      Rule rule = ruleByKey.get(persistedRule.getKey());
+    for (RuleDto persistedRule : existingRules.get(repository.getKey())) {
+      Rule rule = ruleByKey.get(persistedRule.getRuleKey());
       if (rule != null) {
-        updateExistingRule(persistedRule, rule);
-        session.saveWithoutFlush(persistedRule);
+        registeredRules.remove(dtoFrom(rule));
+        updateExistingRule(persistedRule, existingRules.params(persistedRule.getId()), existingRules.tags(persistedRule.getId()), rule);
+        ruleDao.update(persistedRule, sqlSession);
+        registeredRules.add(persistedRule);
         ruleByKey.remove(rule.getKey());
       }
     }
@@ -130,10 +144,10 @@ public final class RegisterRules {
   /**
    * Template rules do not exists in rule repositories, only in database, they have to be updated from their parent.
    */
-  private List<Rule> registerTemplateRules(List<Rule> registeredRules, RulesByRepository existingRules) {
-    List<Rule> templateRules = newArrayList();
-    for (Rule persistedRule : existingRules.rules()) {
-      Rule parent = persistedRule.getParent();
+  private List<RuleDto> registerTemplateRules(List<RuleDto> registeredRules, RulesByRepository existingRules) {
+    List<RuleDto> templateRules = newArrayList();
+    for (RuleDto persistedRule : existingRules.rules()) {
+      RuleDto parent = existingRules.ruleById(persistedRule.getParentId());
       if (parent != null && registeredRules.contains(parent)) {
         persistedRule.setRepositoryKey(parent.getRepositoryKey());
         persistedRule.setLanguage(parent.getLanguage());
@@ -141,7 +155,7 @@ public final class RegisterRules {
         persistedRule.setCreatedAt(Objects.firstNonNull(persistedRule.getCreatedAt(), new Date()));
         persistedRule.setUpdatedAt(new Date());
 
-        session.saveWithoutFlush(persistedRule);
+        ruleDao.update(persistedRule, sqlSession);
         templateRules.add(persistedRule);
       }
     }
@@ -185,31 +199,42 @@ public final class RegisterRules {
     }
   }
 
-  private void updateExistingRule(Rule persistedRule, Rule rule) {
+  private void updateExistingRule(RuleDto persistedRule, Collection<RuleParamDto> ruleParams, Collection<RuleTagDto> persistedTags, Rule rule) {
     LOG.debug("Update existing rule " + rule);
 
     persistedRule.setName(rule.getName());
     persistedRule.setConfigKey(rule.getConfigKey());
     persistedRule.setDescription(rule.getDescription());
-    persistedRule.setSeverity(rule.getSeverity());
+    persistedRule.setSeverity(rule.getSeverity().ordinal());
     persistedRule.setCardinality(rule.getCardinality());
     persistedRule.setStatus(rule.getStatus());
     persistedRule.setLanguage(rule.getLanguage());
     persistedRule.setUpdatedAt(new Date());
 
     // delete deprecated params
-    deleteDeprecatedParameters(persistedRule, rule);
+    deleteDeprecatedParameters(persistedRule, ruleParams, rule);
 
     // add new params and update existing params
-    updateParameters(persistedRule, rule);
+    updateParameters(persistedRule, ruleParams, rule);
+
+    synchronizeTags(persistedRule, persistedTags, rule);
   }
 
-  private void updateParameters(Rule persistedRule, Rule rule) {
+  private void updateParameters(RuleDto persistedRule, Collection<RuleParamDto> ruleParams, Rule rule) {
+    Map<String, RuleParamDto> paramsByKey = Maps.newHashMap();
+    for (RuleParamDto param: ruleParams) {
+      paramsByKey.put(param.getName(), param);
+    }
+
     if (rule.getParams() != null) {
       for (RuleParam param : rule.getParams()) {
-        RuleParam persistedParam = persistedRule.getParam(param.getKey());
+        RuleParamDto persistedParam = paramsByKey.get(param.getKey());
         if (persistedParam == null) {
-          persistedParam = persistedRule.createParameter(param.getKey());
+          persistedParam = new RuleParamDto()
+            .setRuleId(persistedRule.getId())
+            .setName(param.getKey())
+            .setType(param.getType());
+          ruleDao.insert(persistedParam, sqlSession);
         }
         String desc = StringUtils.defaultIfEmpty(
           ruleI18nManager.getParamDescription(rule.getRepositoryKey(), rule.getKey(), param.getKey()),
@@ -218,35 +243,75 @@ public final class RegisterRules {
         persistedParam.setDescription(desc);
         persistedParam.setType(param.getType());
         persistedParam.setDefaultValue(param.getDefaultValue());
+
+        ruleDao.update(persistedParam, sqlSession);
       }
     }
   }
 
-  private void deleteDeprecatedParameters(Rule persistedRule, Rule rule) {
-    if (persistedRule.getParams() != null && !persistedRule.getParams().isEmpty()) {
-      for (Iterator<RuleParam> it = persistedRule.getParams().iterator(); it.hasNext(); ) {
-        RuleParam persistedParam = it.next();
-        if (rule.getParam(persistedParam.getKey()) == null) {
+  private void deleteDeprecatedParameters(RuleDto persistedRule, Collection<RuleParamDto> ruleParams, Rule rule) {
+    if (ruleParams != null && !ruleParams.isEmpty()) {
+      for (Iterator<RuleParamDto> it = ruleParams.iterator(); it.hasNext(); ) {
+        RuleParamDto persistedParam = it.next();
+        if (rule.getParam(persistedParam.getName()) == null) {
           it.remove();
-          session
-            .createQuery("delete from " + ActiveRuleParam.class.getSimpleName() + " where ruleParam=:param")
-            .setParameter("param", persistedParam)
-            .executeUpdate();
+          activeRuleDao.deleteParametersWithParamId(persistedParam.getId(), sqlSession);
+          ruleDao.deleteParam(persistedParam, sqlSession);
+        }
+      }
+    }
+  }
+
+  void synchronizeTags(RuleDto persistedRule, Collection<RuleTagDto> persistedTags, Rule rule) {
+    Set<String> existingSystemTags = Sets.newHashSet();
+
+    for (RuleTagDto existingTag: persistedTags) {
+      String existingTagValue = existingTag.getTag();
+
+      if (existingTag.getType() == RuleTagType.SYSTEM) {
+        existingSystemTags.add(existingTagValue);
+        if (! rule.getTags().contains(existingTagValue)) {
+          ruleDao.deleteTag(existingTag, sqlSession);
         }
+      } else {
+        if (rule.getTags().contains(existingTagValue)) {
+          // Existing admin tag with same value as system tag must be converted
+          ruleDao.deleteTag(existingTag, sqlSession);
+          existingSystemTags.add(existingTagValue);
+          ruleDao.insert(dtoFrom(existingTagValue, persistedRule.getId()), sqlSession);
+        }
+      }
+    }
+
+    for (String newTag: rule.getTags()) {
+      if (! existingSystemTags.contains(newTag)) {
+        ruleDao.insert(dtoFrom(newTag, persistedRule.getId()), sqlSession);
       }
     }
   }
 
+
   private void saveNewRules(Collection<Rule> rules) {
     for (Rule rule : rules) {
       LOG.debug("Save new rule " + rule);
-      rule.setCreatedAt(new Date());
-      session.saveWithoutFlush(rule);
+      RuleDto newRule = dtoFrom(rule);
+      newRule.setCreatedAt(new Date());
+      ruleDao.insert(newRule, sqlSession);
+
+      for(RuleParam param : rule.getParams()) {
+        RuleParamDto newParam = dtoFrom(param, newRule.getId());
+        ruleDao.insert(newParam, sqlSession);
+      }
+
+      for(String tag : rule.getTags()) {
+        RuleTagDto newTag = dtoFrom(tag, newRule.getId());
+        ruleDao.insert(newTag, sqlSession);
+      }
     }
   }
 
-  private void disableDeprecatedRules(RulesByRepository existingRules, List<Rule> registeredRules) {
-    for (Rule rule : existingRules.rules()) {
+  private void disableDeprecatedRules(RulesByRepository existingRules, List<RuleDto> registeredRules) {
+    for (RuleDto rule : existingRules.rules()) {
       if (!registeredRules.contains(rule)) {
         disable(rule);
       }
@@ -260,36 +325,76 @@ public final class RegisterRules {
           return input.getKey().equals(repositoryKey);
         }
       })) {
-        for (Rule rule : existingRules.get(repositoryKey)) {
+        for (RuleDto rule : existingRules.get(repositoryKey)) {
           disable(rule);
         }
       }
     }
   }
 
-  private void disable(Rule rule) {
+  private void disable(RuleDto rule) {
     if (!rule.getStatus().equals(Rule.STATUS_REMOVED)) {
-      LOG.info("Removing rule " + rule.ruleKey());
+      LOG.info("Removing rule " + rule.getRuleKey());
       profilesManager.removeActivatedRules(rule.getId());
-      rule = session.reattach(Rule.class, rule.getId().intValue());
       rule.setStatus(Rule.STATUS_REMOVED);
       rule.setUpdatedAt(new Date());
-      session.save(rule);
-      session.commit();
+      ruleDao.update(rule, sqlSession);
     }
   }
 
+  static RuleDto dtoFrom(Rule rule) {
+    return new RuleDto()
+      .setCardinality(rule.getCardinality())
+      .setConfigKey(rule.getConfigKey())
+      .setDescription(rule.getDescription())
+      .setLanguage(rule.getLanguage())
+      .setName(rule.getName())
+      .setRepositoryKey(rule.getRepositoryKey())
+      .setRuleKey(rule.getKey())
+      .setSeverity(rule.getSeverity().ordinal())
+      .setStatus(rule.getStatus());
+  }
+
+  static RuleParamDto dtoFrom(RuleParam param, Integer ruleId) {
+    return new RuleParamDto()
+      .setRuleId(ruleId)
+      .setDefaultValue(param.getDefaultValue())
+      .setDescription(param.getDescription())
+      .setName(param.getKey())
+      .setType(param.getType());
+  }
+
+  static RuleTagDto dtoFrom(String tag, Integer ruleId) {
+    return new RuleTagDto()
+      .setRuleId(ruleId)
+      .setTag(tag)
+      .setType(RuleTagType.SYSTEM);
+  }
+
   static class RulesByRepository {
-    Multimap<String, Rule> ruleRepositoryList;
+    Multimap<String, RuleDto> ruleRepositoryList;
+    Map<Integer, RuleDto> rulesById;
+    Multimap<Integer, RuleParamDto> params;
+    Multimap<Integer, RuleTagDto> tags;
 
-    RulesByRepository(List<Rule> rules) {
+    RulesByRepository(List<RuleDto> rules, List<RuleParamDto> params, List<RuleTagDto> tags) {
       ruleRepositoryList = ArrayListMultimap.create();
-      for (Rule rule : rules) {
+      rulesById = Maps.newHashMap();
+      for (RuleDto rule : rules) {
         ruleRepositoryList.put(rule.getRepositoryKey(), rule);
+        rulesById.put(rule.getId(), rule);
+      }
+      this.params = ArrayListMultimap.create();
+      for (RuleParamDto param: params) {
+        this.params.put(param.getRuleId(), param);
+      }
+      this.tags = ArrayListMultimap.create();
+      for (RuleTagDto tag: tags) {
+        this.tags.put(tag.getRuleId(), tag);
       }
     }
 
-    Collection<Rule> get(String repositoryKey) {
+    Collection<RuleDto> get(String repositoryKey) {
       return ruleRepositoryList.get(repositoryKey);
     }
 
@@ -297,9 +402,20 @@ public final class RegisterRules {
       return ruleRepositoryList.keySet();
     }
 
-    Collection<Rule> rules() {
+    Collection<RuleDto> rules() {
       return ruleRepositoryList.values();
     }
-  }
 
+    RuleDto ruleById(Integer id) {
+      return rulesById.get(id);
+    }
+
+    Collection<RuleParamDto> params(Integer ruleId) {
+      return params.get(ruleId);
+    }
+
+    Collection<RuleTagDto> tags(Integer ruleId) {
+      return tags.get(ruleId);
+    }
+  }
 }
index 3e740ead9ad14705e876f9d786582f710d54363b..279d3bdd247831a8288f69e1c7f1dddb1e276c1f 100644 (file)
 
 package org.sonar.server.startup;
 
+import org.apache.ibatis.session.SqlSession;
 import org.junit.Before;
 import org.junit.Test;
-import org.sonar.api.rules.*;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RulePriority;
+import org.sonar.api.rules.RuleRepository;
 import org.sonar.api.utils.SonarException;
 import org.sonar.core.i18n.RuleI18nManager;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
+import org.sonar.core.persistence.AbstractDaoTestCase;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.qualityprofile.db.ActiveRuleDao;
+import org.sonar.core.rule.RuleDao;
 import org.sonar.server.configuration.ProfilesManager;
 import org.sonar.server.rule.RuleRegistry;
 
@@ -37,21 +43,33 @@ import static org.fest.assertions.Assertions.assertThat;
 import static org.junit.Assert.fail;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
-public class RegisterRulesTest extends AbstractDbUnitTestCase {
+public class RegisterRulesTest extends AbstractDaoTestCase {
+
+  private static final String[] EXCLUDED_COLUMN_NAMES = {
+    "created_at", "updated_at", "note_data", "note_user_login", "note_created_at", "note_updated_at"};
 
   RegisterRules task;
   ProfilesManager profilesManager;
   RuleRegistry ruleRegistry;
   RuleI18nManager ruleI18nManager;
+  MyBatis myBatis;
+  SqlSession sqlSession;
+  RuleDao ruleDao;
+  ActiveRuleDao activeRuleDao;
 
   @Before
   public void init() {
     profilesManager = mock(ProfilesManager.class);
     ruleRegistry = mock(RuleRegistry.class);
     ruleI18nManager = mock(RuleI18nManager.class);
-    task = new RegisterRules(getSessionFactory(), new RuleRepository[] {new FakeRepository()}, ruleI18nManager, profilesManager, ruleRegistry);
+    myBatis = getMyBatis();
+    ruleDao = new RuleDao(myBatis);
+    activeRuleDao = new ActiveRuleDao(myBatis);
+    task = new RegisterRules(new RuleRepository[] {new FakeRepository()}, ruleI18nManager, profilesManager, ruleRegistry, myBatis, ruleDao, activeRuleDao);
   }
 
   @Test
@@ -60,18 +78,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     task.start();
 
     verify(ruleRegistry).bulkRegisterRules();
-
-    List<Rule> result = getSession().getResults(Rule.class, "pluginName", "fake");
-    assertThat(result.size()).isEqualTo(2);
-
-    Rule first = result.get(0);
-    assertThat(first.getKey()).isEqualTo("rule1");
-    assertThat(first.getRepositoryKey()).isEqualTo("fake");
-    assertThat(first.isEnabled()).isEqualTo(true);
-    assertThat(first.getCreatedAt()).isNotNull();
-    assertThat(first.getStatus()).isEqualTo(Rule.STATUS_READY);
-    assertThat(first.getLanguage()).isEqualTo("java");
-    assertThat(first.getParams().size()).isEqualTo(2);
+    checkTables("should_save_new_repositories", EXCLUDED_COLUMN_NAMES, "rules", "rules_parameters", "rule_tags");
   }
 
   @Test
@@ -79,31 +86,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     setupData("should_update_template_rule_language");
     task.start();
 
-    Rule rule = getSession().getSingleResult(Rule.class, "id", 2);
-    assertThat(rule.getRepositoryKey()).isEqualTo("fake");
-    assertThat(rule.getLanguage()).isEqualTo("java");
-    assertThat(rule.getStatus()).isEqualTo(Rule.STATUS_READY);
-
-    rule = getSession().getSingleResult(Rule.class, "id", 4);
-    assertThat(rule.getRepositoryKey()).isEqualTo("fake");
-    assertThat(rule.getLanguage()).isEqualTo("java");
-    // parent status is now DEPRECATED but template should not be changed
-    assertThat(rule.getStatus()).isEqualTo(Rule.STATUS_READY);
-  }
-
-  @Test
-  public void should_disable_deprecated_repositories() {
-    setupData("shared");
-    task.start();
-
-    List<Rule> rules = getSession()
-        .createQuery("from " + Rule.class.getSimpleName() + " where pluginName<>'fake'")
-        .getResultList();
-    assertThat(rules.size()).isGreaterThan(0);
-    for (Rule rule : rules) {
-      assertThat(rule.isEnabled()).isEqualTo(false);
-      assertThat(rule.getUpdatedAt()).isNotNull();
-    }
+    checkTables("should_update_template_rule_language", EXCLUDED_COLUMN_NAMES, "rules");
   }
 
   @Test
@@ -119,9 +102,9 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     setupData("reactivateDisabledRules");
     task.start();
 
-    Rule rule = getSession().getSingleResult(Rule.class, "id", 1);
-    assertThat(rule.getStatus()).isEqualTo(Rule.STATUS_READY);
-    assertThat(rule.getUpdatedAt()).isNotNull();
+    checkTables("reactivateDisabledRules", EXCLUDED_COLUMN_NAMES, "rules");
+
+    assertThat(ruleDao.selectById(1).getUpdatedAt()).isNotNull();
   }
 
   @Test
@@ -129,9 +112,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     setupData("should_reactivate_disabled_template_rules");
     task.start();
 
-    Rule rule = getSession().getSingleResult(Rule.class, "id", 2);
-    assertThat(rule.getStatus()).isEqualTo(Rule.STATUS_REMOVED);
-    assertThat(rule.getUpdatedAt()).isNotNull();
+    checkTables("should_reactivate_disabled_template_rules", EXCLUDED_COLUMN_NAMES, "rules");
   }
 
   @Test
@@ -139,9 +120,9 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     setupData("notUpdateAlreadyDisabledRule");
     task.start();
 
-    Rule rule = getSession().getSingleResult(Rule.class, "id", 1);
-    assertThat(rule.getStatus()).isEqualTo(Rule.STATUS_REMOVED);
-    assertThat(rule.getUpdatedAt()).isNull();
+    checkTables("should_save_new_repositories", EXCLUDED_COLUMN_NAMES, "rules");
+
+    assertThat(ruleDao.selectById(1).getUpdatedAt()).isNull();
   }
 
   @Test
@@ -149,16 +130,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     setupData("disableDeprecatedActiveRules");
     task.start();
 
-    List<Rule> result = getSession().getResults(Rule.class, "pluginName", "fake");
-    assertThat(result.size()).isEqualTo(3);
-
-    Rule deprecated = result.get(0);
-    assertThat(deprecated.getKey()).isEqualTo("deprecated");
-    assertThat(deprecated.isEnabled()).isEqualTo(false);
-    assertThat(deprecated.getUpdatedAt()).isNotNull();
-
-    assertThat(result.get(1).isEnabled()).isEqualTo(true);
-    assertThat(result.get(2).isEnabled()).isEqualTo(true);
+    checkTables("disableDeprecatedActiveRules", EXCLUDED_COLUMN_NAMES, "rules");
   }
 
   @Test
@@ -166,9 +138,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     setupData("disableDeprecatedActiveRuleParameters");
     task.start();
 
-    ActiveRule arule = getSession().getSingleResult(ActiveRule.class, "id", 1);
-    assertThat(arule.getActiveRuleParams().size()).isEqualTo(2);
-    assertThat(getSession().getSingleResult(ActiveRuleParam.class, "id", 3)).isNull();
+    checkTables("disableDeprecatedActiveRuleParameters", EXCLUDED_COLUMN_NAMES, "rules", "rules_parameters", "active_rules", "active_rule_parameters");
   }
 
   @Test
@@ -176,13 +146,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     setupData("disableDeprecatedRules");
     task.start();
 
-    Rule rule = getSession().getSingleResult(Rule.class, "id", 1);
-    assertThat(rule.isEnabled()).isEqualTo(false);
-    assertThat(rule.getUpdatedAt()).isNotNull();
-
-    rule = getSession().getSingleResult(Rule.class, "id", 2);
-    assertThat(rule.isEnabled()).isEqualTo(false);
-    assertThat(rule.getUpdatedAt()).isNotNull();
+    checkTables("disableDeprecatedRules", EXCLUDED_COLUMN_NAMES, "rules", "rules_parameters");
   }
 
   @Test
@@ -190,17 +154,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     setupData("updadeRuleFields");
     task.start();
 
-    // fields have been updated with new values
-    Rule rule1 = getSession().getSingleResult(Rule.class, "id", 1);
-    assertThat(rule1.getName()).isEqualTo("One");
-    assertThat(rule1.getDescription()).isEqualTo("Description of One");
-    assertThat(rule1.getSeverity()).isEqualTo(RulePriority.BLOCKER);
-    assertThat(rule1.getConfigKey()).isEqualTo("config1");
-    assertThat(rule1.getUpdatedAt()).isNotNull();
-
-    Rule rule2 = getSession().getSingleResult(Rule.class, "id", 2);
-    assertThat(rule2.getStatus()).isEqualTo(Rule.STATUS_DEPRECATED);
-    assertThat(rule2.getUpdatedAt()).isNotNull();
+    checkTables("updadeRuleFields", EXCLUDED_COLUMN_NAMES, "rules", "rules_parameters", "rule_tags");
   }
 
   @Test
@@ -212,17 +166,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     when(ruleI18nManager.getDescription("fake", "rule1")).thenReturn(i18nDescription);
     task.start();
 
-    // fields have been updated with new values
-    Rule rule1 = getSession().getSingleResult(Rule.class, "id", 1);
-    assertThat(rule1.getName()).isEqualTo(i18nName);
-    assertThat(rule1.getDescription()).isEqualTo(i18nDescription);
-    assertThat(rule1.getSeverity()).isEqualTo(RulePriority.BLOCKER);
-    assertThat(rule1.getConfigKey()).isEqualTo("config1");
-    assertThat(rule1.getUpdatedAt()).isNotNull();
-
-    Rule rule2 = getSession().getSingleResult(Rule.class, "id", 2);
-    assertThat(rule2.getStatus()).isEqualTo(Rule.STATUS_DEPRECATED);
-    assertThat(rule2.getUpdatedAt()).isNotNull();
+    checkTables("should_store_bundle_name_and_description_in_database", EXCLUDED_COLUMN_NAMES, "rules");
   }
 
   @Test
@@ -230,22 +174,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     setupData("updateRuleParameters");
     task.start();
 
-    Rule rule = getSession().getSingleResult(Rule.class, "id", 1);
-    assertThat(rule.getParams().size()).isEqualTo(2);
-
-    // new parameter
-    assertThat(rule.getParam("param2")).isNotNull();
-    assertThat(rule.getParam("param2").getDescription()).isEqualTo("parameter two");
-    assertThat(rule.getParam("param2").getDefaultValue()).isEqualTo("default value two");
-
-    // updated parameter
-    assertThat(rule.getParam("param1")).isNotNull();
-    assertThat(rule.getParam("param1").getDescription()).isEqualTo("parameter one");
-    assertThat(rule.getParam("param1").getDefaultValue()).isEqualTo("default value one");
-
-    // deleted parameter
-    assertThat(rule.getParam("deprecated_param")).isNull();
-    assertThat(getSession().getSingleResult(RuleParam.class, "id", 2)).isNull(); // id of deprecated_param is 2
+    checkTables("updateRuleParameters", EXCLUDED_COLUMN_NAMES, "rules", "rules_parameters");
   }
 
   @Test
@@ -253,8 +182,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     setupData("doNotDisableUserRulesIfParentIsEnabled");
     task.start();
 
-    Rule rule = getSession().getSingleResult(Rule.class, "id", 2);
-    assertThat(rule.isEnabled()).isEqualTo(true);
+    checkTables("doNotDisableUserRulesIfParentIsEnabled", EXCLUDED_COLUMN_NAMES, "rules");
   }
 
   @Test
@@ -262,11 +190,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     setupData("disableUserRulesIfParentIsDisabled");
     task.start();
 
-    Rule rule = getSession().getSingleResult(Rule.class, "id", 2);
-    assertThat(rule.isEnabled()).isEqualTo(false);
-    assertThat(rule.getUpdatedAt()).isNotNull();
-
-    assertThat(getSession().getSingleResult(Rule.class, "id", 4).isEnabled()).isEqualTo(false);
+    checkTables("disableUserRulesIfParentIsDisabled", EXCLUDED_COLUMN_NAMES, "rules");
   }
 
   @Test
@@ -275,24 +199,23 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
     setupData("shouldNotDisableManualRules");
     task.start();
 
-    assertThat(getSession().getSingleResult(Rule.class, "id", 1).isEnabled()).isEqualTo(true);
-    assertThat(getSession().getSingleResult(Rule.class, "id", 2).isEnabled()).isEqualTo(false);
+    checkTables("shouldNotDisableManualRules", EXCLUDED_COLUMN_NAMES, "rules");
   }
 
   @Test
   public void volume_testing() {
-    task = new RegisterRules(getSessionFactory(), new RuleRepository[] {new VolumeRepository()}, ruleI18nManager, profilesManager, ruleRegistry);
+    task = new RegisterRules(new RuleRepository[] {new VolumeRepository()}, ruleI18nManager, profilesManager, ruleRegistry, myBatis, ruleDao, activeRuleDao);
     setupData("shared");
     task.start();
 
-    List<Rule> result = getSession().getResults(Rule.class, "status", Rule.STATUS_READY);
-    assertThat(result.size()).isEqualTo(VolumeRepository.SIZE);
+    // There is already one rule in DB
+    assertThat(ruleDao.selectAll()).hasSize(VolumeRepository.SIZE + 1);
   }
 
   // SONAR-3305
   @Test
   public void should_fail_with_rule_without_name() throws Exception {
-    task = new RegisterRules(getSessionFactory(), new RuleRepository[] {new RuleWithoutNameRepository()}, ruleI18nManager, profilesManager, ruleRegistry);
+    task = new RegisterRules(new RuleRepository[] {new RuleWithoutNameRepository()}, ruleI18nManager, profilesManager, ruleRegistry, myBatis, ruleDao, activeRuleDao);
     setupData("shared");
 
     // the rule has no name, it should fail
@@ -312,7 +235,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
   // SONAR-3769
   @Test
   public void should_fail_with_rule_with_blank_name() throws Exception {
-    task = new RegisterRules(getSessionFactory(), new RuleRepository[] {new RuleWithoutNameRepository()}, ruleI18nManager, profilesManager, ruleRegistry);
+    task = new RegisterRules(new RuleRepository[] {new RuleWithoutNameRepository()}, ruleI18nManager, profilesManager, ruleRegistry, myBatis, ruleDao, activeRuleDao);
     setupData("shared");
 
     // the rule has no name, it should fail
@@ -328,7 +251,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
   @Test
   public void should_fail_with_rule_without_description() throws Exception {
     when(ruleI18nManager.getName(anyString(), anyString())).thenReturn("Name");
-    task = new RegisterRules(getSessionFactory(), new RuleRepository[] {new RuleWithoutDescriptionRepository()}, ruleI18nManager, profilesManager, ruleRegistry);
+    task = new RegisterRules(new RuleRepository[] {new RuleWithoutDescriptionRepository()}, ruleI18nManager, profilesManager, ruleRegistry, myBatis, ruleDao, activeRuleDao);
     setupData("shared");
 
     // the rule has no name, it should fail
@@ -348,7 +271,7 @@ public class RegisterRulesTest extends AbstractDbUnitTestCase {
   // http://jira.codehaus.org/browse/SONAR-3722
   @Test
   public void should_fail_with_rule_without_name_in_bundle() throws Exception {
-    task = new RegisterRules(getSessionFactory(), new RuleRepository[] {new RuleWithoutDescriptionRepository()}, ruleI18nManager, profilesManager, ruleRegistry);
+    task = new RegisterRules(new RuleRepository[] {new RuleWithoutDescriptionRepository()}, ruleI18nManager, profilesManager, ruleRegistry, myBatis, ruleDao, activeRuleDao);
     setupData("shared");
 
     // the rule has no name, it should fail
@@ -376,6 +299,7 @@ class FakeRepository extends RuleRepository {
     rule1.setConfigKey("config1");
     rule1.createParameter("param1").setDescription("parameter one").setDefaultValue("default value one");
     rule1.createParameter("param2").setDescription("parameter two").setDefaultValue("default value two");
+    rule1.setTags("tag1", "tag3", "tag5");
 
     Rule rule2 = Rule.create("fake", "rule2", "Two");
     rule2.setDescription("Description of Two");
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/disableDeprecatedActiveRuleParameters-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/disableDeprecatedActiveRuleParameters-result.xml
new file mode 100644 (file)
index 0000000..e373f40
--- /dev/null
@@ -0,0 +1,17 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="One" description="Description of One"
+         status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <rules id="2" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+         status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <rules_parameters id="1" rule_id="1" default_value="default value one" description="parameter one" name="param1" param_type="STRING"/>
+  <rules_parameters id="2" rule_id="1" default_value="default value two" description="parameter two" name="param2" param_type="STRING"/>
+
+  <rules_profiles id="1" version="1" used_profile="true" name="profile name" language="java" />
+  <active_rules id="1" rule_id="1" profile_id="1" failure_level="4" inheritance="[null]" />
+  <active_rule_parameters id="1" active_rule_id="1" rules_parameter_id="1" value="one" rules_parameter_key="[null]"/>
+  <active_rule_parameters id="2" active_rule_id="1" rules_parameter_id="2" value="two" rules_parameter_key="[null]"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/disableDeprecatedActiveRules-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/disableDeprecatedActiveRules-result.xml
new file mode 100644 (file)
index 0000000..20ae08d
--- /dev/null
@@ -0,0 +1,15 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="deprecated-key" plugin_name="deprecated-repo" plugin_config_key="[null]" name="Deprecated" description="[null]"
+         status="REMOVED" priority="4" cardinality="SINGLE" parent_id="[null]" language="[null]"/>
+
+  <rules id="2" plugin_rule_key="deprecated" plugin_name="fake" plugin_config_key="[null]" name="Deprecated fake" description="[null]"
+         status="REMOVED" priority="4" cardinality="SINGLE" parent_id="[null]" language="[null]"/>
+
+  <rules id="3" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="One" description="Description of One"
+         status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <rules id="4" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+         status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/disableDeprecatedRules-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/disableDeprecatedRules-result.xml
new file mode 100644 (file)
index 0000000..f2d4e54
--- /dev/null
@@ -0,0 +1,20 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="deprecated-key" plugin_name="deprecated-repo" plugin_config_key="[null]" name="Deprecated" description="[null]"
+         status="REMOVED" priority="4" cardinality="SINGLE" parent_id="[null]" language="[null]"/>
+
+  <rules id="2" plugin_rule_key="deprecated" plugin_name="fake" plugin_config_key="[null]" name="Deprecated fake" description="[null]"
+         status="REMOVED" priority="4" cardinality="SINGLE" parent_id="[null]" language="[null]"/>
+
+  <rules_parameters id="1" rule_id="1" name="deprecated-prop" description="[null]" param_type="STRING" default_value="[null]"/>
+
+  <rules id="3" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="One" description="Description of One"
+         status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <rules_parameters id="2" rule_id="3" default_value="default value one" description="parameter one" name="param1" param_type="STRING"/>
+  <rules_parameters id="3" rule_id="3" default_value="default value two" description="parameter two" name="param2" param_type="STRING"/>
+
+  <rules id="4" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+         status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/disableUserRulesIfParentIsDisabled-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/disableUserRulesIfParentIsDisabled-result.xml
new file mode 100644 (file)
index 0000000..69b3d0e
--- /dev/null
@@ -0,0 +1,21 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="disabled_rule" plugin_name="fake" plugin_config_key="[null]" name="Disabled rule" description="[null]"
+         status="REMOVED" priority="4" cardinality="MULTIPLE" parent_id="[null]" language="[null]"/>
+
+  <rules id="2" plugin_rule_key="user_rule" plugin_name="fake" plugin_config_key="[null]" name="User rule" description="[null]"
+         status="REMOVED" priority="4" cardinality="SINGLE" parent_id="1" language="[null]"/>
+
+  <rules id="3" plugin_rule_key="disabled_rule2" plugin_name="fake" plugin_config_key="old_config_key2" name="old name2" description="old description2"
+         status="REMOVED" priority="1" cardinality="SINGLE" parent_id="[null]"  language="[null]"/>
+
+  <rules id="4" plugin_rule_key="template_rule2" plugin_name="fake" plugin_config_key="[null]" name="User rule" description="[null]"
+         status="REMOVED" priority="4" cardinality="SINGLE" parent_id="3" language="[null]"/>
+
+  <rules id="5" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="One" description="Description of One"
+         status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <rules id="6" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+         status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/doNotDisableUserRulesIfParentIsEnabled-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/doNotDisableUserRulesIfParentIsEnabled-result.xml
new file mode 100644 (file)
index 0000000..4aa90f3
--- /dev/null
@@ -0,0 +1,12 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="One" description="Description of One"
+     status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <rules id="2" plugin_rule_key="user_rule" plugin_name="fake" plugin_config_key="[null]" name="User rule" description="[null]"
+     status="READY" priority="4" cardinality="SINGLE" parent_id="1" language="java"/>
+
+  <rules id="3" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+     status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/notUpdateAlreadyDisabledRule-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/notUpdateAlreadyDisabledRule-result.xml
new file mode 100644 (file)
index 0000000..c8f9fa8
--- /dev/null
@@ -0,0 +1,9 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="deprecated-key" plugin_name="deprecated-repo" plugin_config_key="[null]" name="Deprecated" description="[null]"
+         status="REMOVED" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <rules id="2" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+                   status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/reactivateDisabledRules-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/reactivateDisabledRules-result.xml
new file mode 100644 (file)
index 0000000..5efffba
--- /dev/null
@@ -0,0 +1,9 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="One" description="Description of One"
+                   status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <rules id="2" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+                   status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/shouldNotDisableManualRules-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/shouldNotDisableManualRules-result.xml
new file mode 100644 (file)
index 0000000..fed6aea
--- /dev/null
@@ -0,0 +1,15 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="PerformanceIssue" plugin_name="manual" plugin_config_key="[null]" name="Performance Issue" description="[null]"
+         status="READY" priority="[null]" cardinality="SINGLE" parent_id="[null]" language="[null]"/>
+
+  <rules id="2" plugin_rule_key="IllegalExceptionCheck" plugin_name="checkstyle" plugin_config_key="[null]" name="Illegal Exception" description="[null]"
+         status="REMOVED" priority="4" cardinality="SINGLE" parent_id="[null]" language="[null]"/>
+
+  <rules id="3" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="One" description="Description of One"
+         status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <rules id="4" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+         status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_disable_deprecated_repositories-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_disable_deprecated_repositories-result.xml
new file mode 100644 (file)
index 0000000..c360f76
--- /dev/null
@@ -0,0 +1,17 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="deprecated-key" plugin_name="deprecated-repo" plugin_config_key="[null]" name="Deprecated" description="[null]"
+     status="REMOVED" priority="4" cardinality="SINGLE" parent_id="[null]" language="[null]"/>
+
+  <rules id="2" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="One" description="Description of One"
+                   status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+  <rules_parameters id="1" rule_id="2" default_value="default value one" description="parameter one" name="param1" param_type="STRING"/>
+  <rules_parameters id="2" rule_id="2" default_value="default value two" description="parameter two" name="param2" param_type="STRING"/>
+  <rule_tags id="1" rule_id="2" tag="tag1" tag_type="SYSTEM"/>
+  <rule_tags id="2" rule_id="2" tag="tag3" tag_type="SYSTEM"/>
+  <rule_tags id="3" rule_id="2" tag="tag5" tag_type="SYSTEM"/>
+
+  <rules id="3" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+                   status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+  
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_reactivate_disabled_template_rules-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_reactivate_disabled_template_rules-result.xml
new file mode 100644 (file)
index 0000000..3352ac6
--- /dev/null
@@ -0,0 +1,12 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="One" description="Description of One"
+         status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <rules id="2" plugin_rule_key="user_rule" plugin_name="fake" plugin_config_key="[null]" name="User rule" description="[null]"
+         status="REMOVED" priority="4" cardinality="SINGLE" parent_id="1" language="java"/>
+
+  <rules id="3" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+         status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_save_new_repositories-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_save_new_repositories-result.xml
new file mode 100644 (file)
index 0000000..065440b
--- /dev/null
@@ -0,0 +1,17 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="deprecated-key" plugin_name="deprecated-repo" plugin_config_key="[null]" name="Deprecated" description="[null]"
+     status="REMOVED" priority="4" cardinality="SINGLE" parent_id="[null]" language="[null]"/>
+
+  <rules id="2" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="One" description="Description of One"
+                   status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+  <rules_parameters id="1" rule_id="2" default_value="default value one" description="parameter one" name="param1" param_type="STRING"/>
+  <rules_parameters id="2" rule_id="2" default_value="default value two" description="parameter two" name="param2" param_type="STRING"/>
+  <rule_tags id="1" rule_id="2" tag="tag1" tag_type="SYSTEM"/>
+  <rule_tags id="2" rule_id="2" tag="tag3" tag_type="SYSTEM"/>
+  <rule_tags id="3" rule_id="2" tag="tag5" tag_type="SYSTEM"/>
+
+  <rules id="3" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+                   status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+  
+</dataset>
\ No newline at end of file
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_store_bundle_name_and_description_in_database-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_store_bundle_name_and_description_in_database-result.xml
new file mode 100644 (file)
index 0000000..b7d93c5
--- /dev/null
@@ -0,0 +1,9 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="The One" description="The Description of One"
+     status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <rules id="2" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+     status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+</dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_update_template_rule_language-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/should_update_template_rule_language-result.xml
new file mode 100644 (file)
index 0000000..617e118
--- /dev/null
@@ -0,0 +1,17 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="One" description="Description of One"
+         status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <!-- Instance of old rule 1 :/ -->
+  <rules id="2" plugin_rule_key="template_rule1" plugin_name="fake" plugin_config_key="[null]" name="User rule" description="[null]"
+         status="READY" priority="4" cardinality="SINGLE" parent_id="1" language="java"/>
+
+  <rules id="3" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+         status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <!-- Template of old rule 3 :/ -->
+  <rules id="4" plugin_rule_key="template_rule2" plugin_name="fake" plugin_config_key="[null]" name="User rule" description="[null]"
+         status="READY" priority="4" cardinality="SINGLE" parent_id="3" language="java"/>
+
+</dataset>
\ No newline at end of file
index a5f4cb7e72f7c71b9f1ac9c7bf05e23f60fcc98e..68bf24c19365d7bf6da927df092a74e1a82b1a6f 100644 (file)
@@ -1,16 +1,16 @@
 <dataset>
 
   <rules id="1" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="[null]" name="Rule one" description="[null]"
-         status="READY" priority="4" cardinality="MULTIPLE" parent_id="[null]"/>
+         status="READY" priority="4" cardinality="MULTIPLE" parent_id="[null]" language="[null]"/>
 
-  <!-- Template of rule 1 -->
+  <!-- Instance of rule 1 -->
   <rules id="2" plugin_rule_key="template_rule1" plugin_name="fake" plugin_config_key="[null]" name="User rule" description="[null]"
-         status="[null]" priority="4" cardinality="SINGLE" parent_id="1"/>
+         status="READY" priority="4" cardinality="SINGLE" parent_id="1"/>
 
   <rules id="3" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="old_config_key2" name="old name2" description="old description2"
-         status="DEPRECATED" priority="1" cardinality="SINGLE" parent_id="[null]" />
+         status="DEPRECATED" priority="1" cardinality="MULTIPLE" parent_id="[null]" />
 
-  <!-- Template of rule 3 -->
+  <!-- Instance of rule 3 -->
   <rules id="4" plugin_rule_key="template_rule2" plugin_name="fake" plugin_config_key="[null]" name="User rule" description="[null]"
          status="READY" priority="4" cardinality="SINGLE" parent_id="3"/>
 
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/updadeRuleFields-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/updadeRuleFields-result.xml
new file mode 100644 (file)
index 0000000..a4b0f4c
--- /dev/null
@@ -0,0 +1,17 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="One" description="Description of One"
+                   status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+  <rules_parameters id="1" rule_id="1" default_value="default value one" description="parameter one" name="param1" param_type="STRING"/>
+  <rules_parameters id="2" rule_id="1" default_value="default value two" description="parameter two" name="param2" param_type="STRING"/>
+
+  <rule_tags id="1" rule_id="1" tag="tag1" tag_type="SYSTEM"/>
+  <rule_tags id="4" rule_id="1" tag="tag4" tag_type="ADMIN"/>
+  <rule_tags id="5" rule_id="1" tag="tag3" tag_type="SYSTEM"/>
+  <rule_tags id="6" rule_id="1" tag="tag5" tag_type="SYSTEM"/>
+
+  <rules id="2" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+     status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+</dataset>
index 34a705682bd3a8ab5367c030b109ce8da3de0f4a..698cfedd8681a74f5c43ed14192bd81bfd27017e 100644 (file)
@@ -3,9 +3,15 @@
   <rules id="1" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="old_config_key" name="old name" description="old description"
          status="READY" priority="2" cardinality="SINGLE" parent_id="[null]" />
 
+  <rules_parameters id="1" rule_id="1" name="param1" description="[null]" param_type="STRING"/>
+
+  <rule_tags id="1" rule_id="1" tag="tag1" tag_type="SYSTEM"/>
+  <rule_tags id="2" rule_id="1" tag="tag2" tag_type="SYSTEM"/>
+  <rule_tags id="3" rule_id="1" tag="tag3" tag_type="ADMIN"/>
+  <rule_tags id="4" rule_id="1" tag="tag4" tag_type="ADMIN"/>
+
   <rules id="2" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="old_config_key2" name="old name2" description="old description2"
          status="READY" priority="1" cardinality="SINGLE" parent_id="[null]" />
 
-  <rules_parameters id="1" rule_id="1" name="param1" description="[null]" param_type="STRING"/>
 
 </dataset>
diff --git a/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/updateRuleParameters-result.xml b/sonar-server/src/test/resources/org/sonar/server/startup/RegisterRulesTest/updateRuleParameters-result.xml
new file mode 100644 (file)
index 0000000..d8e3f0e
--- /dev/null
@@ -0,0 +1,11 @@
+<dataset>
+
+  <rules id="1" plugin_rule_key="rule1" plugin_name="fake" plugin_config_key="config1" name="One" description="Description of One"
+                   status="READY" priority="4" cardinality="SINGLE" parent_id="[null]" language="java"/>
+  <rules_parameters id="1" rule_id="1" default_value="default value one" description="parameter one" name="param1" param_type="STRING"/>
+  <rules_parameters id="3" rule_id="1" default_value="default value two" description="parameter two" name="param2" param_type="STRING"/>
+
+  <rules id="2" plugin_rule_key="rule2" plugin_name="fake" plugin_config_key="rule2" name="Two" description="Description of Two"
+                   status="DEPRECATED" priority="0" cardinality="SINGLE" parent_id="[null]" language="java"/>
+
+</dataset>