]> source.dussan.org Git - sonarqube.git/commitdiff
Fix some quality flaws
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Tue, 17 Jun 2014 09:51:56 +0000 (11:51 +0200)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Tue, 17 Jun 2014 09:51:56 +0000 (11:51 +0200)
14 files changed:
sonar-batch/src/main/java/org/sonar/batch/issue/IssueFilters.java
sonar-batch/src/main/java/org/sonar/batch/rule/RulesProvider.java
sonar-batch/src/main/java/org/sonar/batch/rule/UsedQProfiles.java
sonar-core/src/main/java/org/sonar/core/activity/db/package-info.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/activity/package-info.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/cluster/NullQueue.java
sonar-core/src/main/java/org/sonar/core/cluster/QueueAction.java
sonar-core/src/main/java/org/sonar/core/cluster/WorkQueue.java
sonar-core/src/main/java/org/sonar/core/qualityprofile/db/ActiveRuleDao.java
sonar-core/src/test/java/org/sonar/core/qualityprofile/db/ActiveRuleDaoTest.java
sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java
sonar-plugin-api/src/main/java/org/sonar/api/rules/ActiveRule.java
sonar-server/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleNormalizer.java
sonar-server/src/main/java/org/sonar/server/rule/index/RuleNormalizer.java

index 79b576d3398e7439ccdd81a4494fb94ba1117f92..b43f98f6d2770dc8fd33897039c6241b3714985d 100644 (file)
@@ -34,22 +34,22 @@ public class IssueFilters implements BatchExtension {
   private final org.sonar.api.issue.IssueFilter[] exclusionFilters;
   private final IssueFilter[] filters;
 
-  public IssueFilters(ViolationFilters deprecatedFilters, DeprecatedViolations deprecatedViolations, org.sonar.api.issue.IssueFilter[] exclusionFilters, IssueFilter[] filters) {
+  public IssueFilters(@Nullable ViolationFilters deprecatedFilters, @Nullable DeprecatedViolations deprecatedViolations, org.sonar.api.issue.IssueFilter[] exclusionFilters, IssueFilter[] filters) {
     this.deprecatedFilters = deprecatedFilters;
     this.deprecatedViolations = deprecatedViolations;
     this.exclusionFilters = exclusionFilters;
     this.filters = filters;
   }
 
-  public IssueFilters(ViolationFilters deprecatedFilters, DeprecatedViolations deprecatedViolations, IssueFilter[] filters) {
+  public IssueFilters(@Nullable ViolationFilters deprecatedFilters, @Nullable DeprecatedViolations deprecatedViolations, IssueFilter[] filters) {
     this(deprecatedFilters, deprecatedViolations, new org.sonar.api.issue.IssueFilter[0], filters);
   }
 
-  public IssueFilters(ViolationFilters deprecatedFilters, DeprecatedViolations deprecatedViolations, org.sonar.api.issue.IssueFilter[] exclusionFilters) {
+  public IssueFilters(@Nullable ViolationFilters deprecatedFilters, @Nullable DeprecatedViolations deprecatedViolations, org.sonar.api.issue.IssueFilter[] exclusionFilters) {
     this(deprecatedFilters, deprecatedViolations, exclusionFilters, new IssueFilter[0]);
   }
 
-  public IssueFilters(ViolationFilters deprecatedFilters, DeprecatedViolations deprecatedViolations) {
+  public IssueFilters(@Nullable ViolationFilters deprecatedFilters, @Nullable DeprecatedViolations deprecatedViolations) {
     this(deprecatedFilters, deprecatedViolations, new org.sonar.api.issue.IssueFilter[0]);
   }
 
@@ -80,7 +80,7 @@ public class IssueFilters implements BatchExtension {
           return false;
         }
       }
-      if (deprecatedFilters != null && !deprecatedFilters.isEmpty()) {
+      if (deprecatedFilters != null && !deprecatedFilters.isEmpty() && deprecatedViolations != null) {
         Violation v = violation != null ? violation : deprecatedViolations.toViolation(issue);
         return !deprecatedFilters.isIgnored(v);
       }
index d9bf9917a4dc6403f1b98fc20e7dc2ed164ff45a..744c5caa5ba840eb165fb99b2d2af4643e34a34a 100644 (file)
@@ -33,7 +33,6 @@ import org.sonar.api.batch.rule.Rules;
 import org.sonar.api.batch.rule.internal.NewRule;
 import org.sonar.api.batch.rule.internal.RulesBuilder;
 import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.utils.Durations;
 import org.sonar.api.utils.TimeProfiler;
 import org.sonar.core.rule.RuleDao;
index 5973a74c59342029225af8496589a15a47cd9db0..9ae587d71baf23e093e14fb33bc6ac2cfb58d3d5 100644 (file)
@@ -37,12 +37,13 @@ import java.util.Map;
 @Immutable
 public class UsedQProfiles {
 
-  private Map<Integer, QProfileWithId> profilesById = Maps.newLinkedHashMap();
+  private final Map<Integer, QProfileWithId> profilesById = Maps.newLinkedHashMap();
 
   private UsedQProfiles() {
+    // only static
   }
 
-  public static final UsedQProfiles fromProfiles(Iterable<QProfileWithId> profiles) {
+  public static UsedQProfiles fromProfiles(Iterable<QProfileWithId> profiles) {
     UsedQProfiles result = new UsedQProfiles();
     for (QProfileWithId qProfile : profiles) {
       result.add(qProfile);
@@ -50,15 +51,15 @@ public class UsedQProfiles {
     return result;
   }
 
-  public static final UsedQProfiles empty() {
+  public static UsedQProfiles empty() {
     return new UsedQProfiles();
   }
 
-  public static final UsedQProfiles fromProfiles(QProfileWithId... profiles) {
+  public static UsedQProfiles fromProfiles(QProfileWithId... profiles) {
     return fromProfiles(Arrays.asList(profiles));
   }
 
-  public static final UsedQProfiles fromJSON(String json) {
+  public static UsedQProfiles fromJSON(String json) {
     UsedQProfiles result = new UsedQProfiles();
     JsonArray root = new JsonParser().parse(json).getAsJsonArray();
     for (JsonElement elt : root) {
@@ -73,7 +74,8 @@ public class UsedQProfiles {
     JsonWriter writer = JsonWriter.of(json);
     writer.beginArray();
     for (QProfileWithId qProfile : profilesById.values()) {
-      writer.beginObject()
+      writer
+        .beginObject()
         .prop("id", qProfile.id())
         .prop("name", qProfile.name())
         .prop("version", qProfile.version())
diff --git a/sonar-core/src/main/java/org/sonar/core/activity/db/package-info.java b/sonar-core/src/main/java/org/sonar/core/activity/db/package-info.java
new file mode 100644 (file)
index 0000000..ddc4a6d
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.core.activity.db;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-core/src/main/java/org/sonar/core/activity/package-info.java b/sonar-core/src/main/java/org/sonar/core/activity/package-info.java
new file mode 100644 (file)
index 0000000..8c6baa9
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.core.activity;
+
+import javax.annotation.ParametersAreNonnullByDefault;
index d67576c418c140c17c4b298d5ffbc217337fa224..235d2078fef75f4f22d2011f3118a39aec6bb32f 100644 (file)
@@ -21,16 +21,15 @@ package org.sonar.core.cluster;
 
 import java.util.List;
 
-
 public class NullQueue implements WorkQueue<QueueAction> {
 
   @Override
   public void enqueue(QueueAction action) {
-
+    // do nothing
   }
 
   @Override
   public void enqueue(List<QueueAction> actions) {
-
+    // do nothing
   }
 }
index 99a7ef3a1cfa79793d733eb9673a54999de7ca67..f83078d3bb5ce0fa8b086b7a6c3458779d7418e6 100644 (file)
@@ -38,7 +38,7 @@ public abstract class QueueAction implements Runnable {
   @Override
   public void run(){
     this.doExecute();
-    if(latch != null){
+    if (latch != null){
       latch.countDown();
     }
   }
index bdd583b733a50102ee57a88e8dcc84d0e5e6bd91..9b4141f510defa5f4ef758ce6db556b007fa65e1 100644 (file)
@@ -21,7 +21,6 @@ package org.sonar.core.cluster;
 
 import java.util.List;
 
-
 public interface WorkQueue<K extends QueueAction> {
 
   void enqueue(K action);
index a7f01729ccc67d08088a2c837a3b6e4d1ee374d2..0f3af1f521f1c78d039f816edd82854bfc786559 100644 (file)
@@ -38,16 +38,6 @@ public class ActiveRuleDao implements ServerComponent {
     session.getMapper(ActiveRuleMapper.class).insert(dto);
   }
 
-  public void insert(ActiveRuleDto dto) {
-    SqlSession session = mybatis.openSession(false);
-    try {
-      insert(dto, session);
-      session.commit();
-    } finally {
-      MyBatis.closeQuietly(session);
-    }
-  }
-
   public List<ActiveRuleDto> selectByProfileId(int profileId) {
     SqlSession session = mybatis.openSession(false);
     try {
@@ -61,16 +51,6 @@ public class ActiveRuleDao implements ServerComponent {
     session.getMapper(ActiveRuleMapper.class).insertParameter(dto);
   }
 
-  public void insert(ActiveRuleParamDto dto) {
-    SqlSession session = mybatis.openSession(false);
-    try {
-      insert(dto, session);
-      session.commit();
-    } finally {
-      MyBatis.closeQuietly(session);
-    }
-  }
-
   public List<ActiveRuleParamDto> selectParamsByProfileId(int profileId) {
     SqlSession session = mybatis.openSession(false);
     try {
index 108525d1b8b64e32a4ae2fb1e06dc1216ae4d43e..30ef5ac5673a0aea57d47e1f9d278ff1165e9ae1 100644 (file)
@@ -22,12 +22,11 @@ package org.sonar.core.qualityprofile.db;
 
 import org.junit.Before;
 import org.junit.Test;
-import org.sonar.api.rule.Severity;
 import org.sonar.core.persistence.AbstractDaoTestCase;
+import org.sonar.core.persistence.DbSession;
 
 import java.util.List;
 
-import static junit.framework.Assert.fail;
 import static org.fest.assertions.Assertions.assertThat;
 
 public class ActiveRuleDaoTest extends AbstractDaoTestCase {
@@ -39,21 +38,6 @@ public class ActiveRuleDaoTest extends AbstractDaoTestCase {
     dao = new ActiveRuleDao(getMyBatis());
   }
 
-  @Test
-  public void insert() {
-    setupData("empty");
-
-    ActiveRuleDto dto = new ActiveRuleDto()
-      .setProfileId(1)
-      .setRuleId(10)
-      .setSeverity(Severity.MAJOR)
-      .setInheritance("INHERITED");
-
-    dao.insert(dto);
-
-    checkTables("insert", "active_rules");
-  }
-
   @Test
   public void select_by_profile() {
     setupData("shared");
@@ -66,13 +50,15 @@ public class ActiveRuleDaoTest extends AbstractDaoTestCase {
   public void insert_parameter() {
     setupData("empty");
 
+    DbSession session = getMyBatis().openSession(false);
     ActiveRuleParamDto dto = new ActiveRuleParamDto()
       .setActiveRuleId(1)
       .setRulesParameterId(1)
       .setKey("max")
       .setValue("20");
-
-    dao.insert(dto);
+    dao.insert(dto, session);
+    session.commit();
+    session.close();
 
     checkTables("insert_parameter", "active_rule_parameters");
   }
@@ -83,31 +69,4 @@ public class ActiveRuleDaoTest extends AbstractDaoTestCase {
 
     assertThat(dao.selectParamsByProfileId(1)).hasSize(2);
   }
-
-  @Test
-  public void fail_unique_rule_index() {
-    setupData("empty");
-
-    ActiveRuleDto dto = new ActiveRuleDto()
-      .setProfileId(1)
-      .setRuleId(10)
-      .setSeverity(Severity.MAJOR)
-      .setInheritance("INHERITED");
-
-    dao.insert(dto);
-
-    try {
-      ActiveRuleDto dto2 = new ActiveRuleDto()
-        .setProfileId(1)
-        .setRuleId(10)
-        .setSeverity(Severity.MAJOR)
-        .setInheritance("INHERITED");
-
-      dao.insert(dto2);
-      fail();
-    } catch (Exception e) {
-
-    }
-
-  }
 }
index 4800993bbde4a884c6d97b9609f9afab88f25412..07b71645d150875ee0787b873a7e50bf61441fb1 100644 (file)
@@ -34,7 +34,6 @@ import org.sonar.api.utils.MessageException;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
-import javax.persistence.*;
 
 import java.util.ArrayList;
 import java.util.List;
index 7945ba1411f74de6eebd0440657fb1d96b3fdb65..c9e14d6f8363b5071ea158a136adb83fdb323260 100644 (file)
@@ -30,9 +30,6 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
-/**
- * A class to map an ActiveRule to the hibernate model
- */
 public class ActiveRule implements Cloneable {
 
   public static final String INHERITED = "INHERITED";
index a5ddecd6ec6fd94c978785d650d224298223bd20..9d96f913394804b8983a6725fea4c18f8124fc74 100644 (file)
@@ -48,15 +48,14 @@ public class ActiveRuleNormalizer extends BaseNormalizer<ActiveRuleDto, ActiveRu
 
   public static class ActiveRuleField extends Indexable {
 
-    public static IndexField KEY = addSortableAndSearchable(IndexField.Type.STRING, "key");
-    public static IndexField INHERITANCE = add(IndexField.Type.STRING, "inheritance");
-    public static IndexField PROFILE_KEY = add(IndexField.Type.STRING, "profile");
-    public static IndexField SEVERITY = add(IndexField.Type.STRING, "severity");
-    public static IndexField PARENT_KEY = add(IndexField.Type.STRING, "parentKey");
-    public static IndexField RULE_KEY = add(IndexField.Type.STRING, "ruleKey");
-    public static IndexField PARAMS = addEmbedded("params", ActiveRuleParamField.ALL_FIELDS);
-
-    public static Set<IndexField> ALL_FIELDS = getAllFields();
+    public static final IndexField KEY = addSortableAndSearchable(IndexField.Type.STRING, "key");
+    public static final IndexField INHERITANCE = add(IndexField.Type.STRING, "inheritance");
+    public static final IndexField PROFILE_KEY = add(IndexField.Type.STRING, "profile");
+    public static final IndexField SEVERITY = add(IndexField.Type.STRING, "severity");
+    public static final IndexField PARENT_KEY = add(IndexField.Type.STRING, "parentKey");
+    public static final IndexField RULE_KEY = add(IndexField.Type.STRING, "ruleKey");
+    public static final IndexField PARAMS = addEmbedded("params", ActiveRuleParamField.ALL_FIELDS);
+    public static final Set<IndexField> ALL_FIELDS = getAllFields();
 
     private static Set<IndexField> getAllFields() {
       Set<IndexField> fields = new HashSet<IndexField>();
@@ -65,7 +64,7 @@ public class ActiveRuleNormalizer extends BaseNormalizer<ActiveRuleDto, ActiveRu
           try {
             fields.add(IndexField.class.cast(classField.get(null)));
           } catch (IllegalAccessException e) {
-            e.printStackTrace();
+            throw new IllegalStateException("Can not introspect active rule fields", e);
           }
         }
       }
@@ -75,10 +74,9 @@ public class ActiveRuleNormalizer extends BaseNormalizer<ActiveRuleDto, ActiveRu
   }
 
   public static class ActiveRuleParamField extends Indexable {
-    public static IndexField NAME = add(IndexField.Type.STRING, "name");
-    public static IndexField VALUE = add(IndexField.Type.STRING, "value");
-
-    public static Set<IndexField> ALL_FIELDS = getAllFields();
+    public static final IndexField NAME = add(IndexField.Type.STRING, "name");
+    public static final IndexField VALUE = add(IndexField.Type.STRING, "value");
+    public static final Set<IndexField> ALL_FIELDS = getAllFields();
 
     private static Set<IndexField> getAllFields() {
       Set<IndexField> fields = new HashSet<IndexField>();
@@ -87,7 +85,7 @@ public class ActiveRuleNormalizer extends BaseNormalizer<ActiveRuleDto, ActiveRu
           try {
             fields.add(IndexField.class.cast(classField.get(null)));
           } catch (IllegalAccessException e) {
-            e.printStackTrace();
+            throw new IllegalStateException("Can not introspect active rule param fields", e);
           }
         }
       }
@@ -106,7 +104,7 @@ public class ActiveRuleNormalizer extends BaseNormalizer<ActiveRuleDto, ActiveRu
     try {
       requests.addAll(normalize(db.activeRuleDao().getNullableByKey(dbSession, key)));
       for (ActiveRuleParamDto param : db.activeRuleDao().findParamsByActiveRuleKey(dbSession, key)) {
-        requests.addAll(this.normalizeNested(param, key));
+        requests.addAll(normalizeNested(param, key));
       }
     } finally {
       dbSession.close();
index 3cbf9f76df9959e1f7b9187eebd1cabf1fe8b529..37bc8f978766cb276c412070852bd0489cb992c6 100644 (file)
@@ -45,12 +45,10 @@ public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> {
   public static final class RuleParamField extends Indexable {
 
     public static final IndexField NAME = add(IndexField.Type.STRING, "name");
-
     public static final IndexField TYPE = add(IndexField.Type.STRING, "type");
     public static final IndexField DESCRIPTION = addSearchable(IndexField.Type.TEXT, "description");
     public static final IndexField DEFAULT_VALUE = add(IndexField.Type.STRING, "defaultValue");
-
-    public static Set<IndexField> ALL_FIELDS = getAllFields();
+    public static final Set<IndexField> ALL_FIELDS = getAllFields();
 
     private static Set<IndexField> getAllFields() {
       Set<IndexField> fields = new HashSet<IndexField>();
@@ -59,7 +57,7 @@ public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> {
           try {
             fields.add(IndexField.class.cast(classField.get(null)));
           } catch (IllegalAccessException e) {
-            e.printStackTrace();
+            throw new IllegalStateException("Can not introspect rule index fields", e);
           }
         }
       }
@@ -69,36 +67,40 @@ public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> {
 
   public static final class RuleField extends Indexable {
 
+    /**
+     * @deprecated because key should be used instead of id. This field is kept for compatibility with
+     * SQALE console.
+     */
     @Deprecated
-    public static IndexField ID = addSortable(IndexField.Type.NUMERIC, "id");
-
-    public static IndexField KEY = addSortable(IndexField.Type.STRING, "key");
-    public static IndexField _KEY = add(IndexField.Type.STRING, "_key");
-    public static IndexField REPOSITORY = add(IndexField.Type.STRING, "repo");
-
-    public static IndexField NAME = addSortableAndSearchable(IndexField.Type.STRING, "name");
-    public static IndexField CREATED_AT = addSortable(IndexField.Type.DATE, "createdAt");
-    public static IndexField UPDATED_AT = addSortable(IndexField.Type.DATE, "updatedAt");
-    public static IndexField HTML_DESCRIPTION = addSearchable(IndexField.Type.TEXT, "htmlDesc");
-    public static IndexField SEVERITY = add(IndexField.Type.STRING, "severity");
-    public static IndexField STATUS = add(IndexField.Type.STRING, "status");
-    public static IndexField LANGUAGE = add(IndexField.Type.STRING, "lang");
-    public static IndexField TAGS = add(IndexField.Type.STRING, "tags");
-    public static IndexField SYSTEM_TAGS = add(IndexField.Type.STRING, "sysTags");
-    public static IndexField INTERNAL_KEY = add(IndexField.Type.STRING, "internalKey");
-    public static IndexField IS_TEMPLATE = add(IndexField.Type.BOOLEAN, "isTemplate");
-    public static IndexField TEMPLATE_KEY = add(IndexField.Type.STRING, "templateKey");
-    public static IndexField DEBT_FUNCTION_TYPE = add(IndexField.Type.STRING, "debtRemFnType");
-    public static IndexField DEBT_FUNCTION_COEFFICIENT = add(IndexField.Type.STRING, "debtRemFnCoefficient");
-    public static IndexField DEBT_FUNCTION_OFFSET = add(IndexField.Type.STRING, "debtRemFnOffset");
-    public static IndexField SUB_CHARACTERISTIC = add(IndexField.Type.STRING, "debtSubChar");
-    public static IndexField CHARACTERISTIC = add(IndexField.Type.STRING, "debtChar");
-    public static IndexField NOTE = add(IndexField.Type.TEXT, "markdownNote");
-    public static IndexField NOTE_LOGIN = add(IndexField.Type.STRING, "noteLogin");
-    public static IndexField NOTE_CREATED_AT = add(IndexField.Type.DATE, "noteCreatedAt");
-    public static IndexField NOTE_UPDATED_AT = add(IndexField.Type.DATE, "noteUpdatedAt");
-    public static IndexField _TAGS = addSearchable(IndexField.Type.STRING, "_tags");
-    public static IndexField PARAMS = addEmbedded("params", RuleParamField.ALL_FIELDS);
+    public static final IndexField ID = addSortable(IndexField.Type.NUMERIC, "id");
+
+    public static final IndexField KEY = addSortable(IndexField.Type.STRING, "key");
+    public static final IndexField _KEY = add(IndexField.Type.STRING, "_key");
+    public static final IndexField REPOSITORY = add(IndexField.Type.STRING, "repo");
+
+    public static final IndexField NAME = addSortableAndSearchable(IndexField.Type.STRING, "name");
+    public static final IndexField CREATED_AT = addSortable(IndexField.Type.DATE, "createdAt");
+    public static final IndexField UPDATED_AT = addSortable(IndexField.Type.DATE, "updatedAt");
+    public static final IndexField HTML_DESCRIPTION = addSearchable(IndexField.Type.TEXT, "htmlDesc");
+    public static final IndexField SEVERITY = add(IndexField.Type.STRING, "severity");
+    public static final IndexField STATUS = add(IndexField.Type.STRING, "status");
+    public static final IndexField LANGUAGE = add(IndexField.Type.STRING, "lang");
+    public static final IndexField TAGS = add(IndexField.Type.STRING, "tags");
+    public static final IndexField SYSTEM_TAGS = add(IndexField.Type.STRING, "sysTags");
+    public static final IndexField INTERNAL_KEY = add(IndexField.Type.STRING, "internalKey");
+    public static final IndexField IS_TEMPLATE = add(IndexField.Type.BOOLEAN, "isTemplate");
+    public static final IndexField TEMPLATE_KEY = add(IndexField.Type.STRING, "templateKey");
+    public static final IndexField DEBT_FUNCTION_TYPE = add(IndexField.Type.STRING, "debtRemFnType");
+    public static final IndexField DEBT_FUNCTION_COEFFICIENT = add(IndexField.Type.STRING, "debtRemFnCoefficient");
+    public static final IndexField DEBT_FUNCTION_OFFSET = add(IndexField.Type.STRING, "debtRemFnOffset");
+    public static final IndexField SUB_CHARACTERISTIC = add(IndexField.Type.STRING, "debtSubChar");
+    public static final IndexField CHARACTERISTIC = add(IndexField.Type.STRING, "debtChar");
+    public static final IndexField NOTE = add(IndexField.Type.TEXT, "markdownNote");
+    public static final IndexField NOTE_LOGIN = add(IndexField.Type.STRING, "noteLogin");
+    public static final IndexField NOTE_CREATED_AT = add(IndexField.Type.DATE, "noteCreatedAt");
+    public static final IndexField NOTE_UPDATED_AT = add(IndexField.Type.DATE, "noteUpdatedAt");
+    public static final IndexField _TAGS = addSearchable(IndexField.Type.STRING, "_tags");
+    public static final IndexField PARAMS = addEmbedded("params", RuleParamField.ALL_FIELDS);
 
 
     public static Set<IndexField> ALL_FIELDS = getAllFields();
@@ -136,16 +138,16 @@ public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> {
   @Override
   public List<UpdateRequest> normalize(RuleKey key) {
     DbSession dbSession = db.openSession(false);
-    List<UpdateRequest> requests = new ArrayList<UpdateRequest>();
     try {
+      List<UpdateRequest> requests = new ArrayList<UpdateRequest>();
       requests.addAll(normalize(db.ruleDao().getNullableByKey(dbSession, key)));
       for (RuleParamDto param : db.ruleDao().findRuleParamsByRuleKey(dbSession, key)) {
         requests.addAll(normalizeNested(param, key));
       }
+      return requests;
     } finally {
       dbSession.close();
     }
-    return requests;
   }
 
   @Override
@@ -246,7 +248,7 @@ public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> {
 
   @Override
   public List<UpdateRequest> normalizeNested(Object object, RuleKey key) {
-    Preconditions.checkArgument(key != null, "key of Rule must be set");
+    Preconditions.checkNotNull(key, "key of rule must be set");
     if (object.getClass().isAssignableFrom(RuleParamDto.class)) {
       return nestedUpdate((RuleParamDto) object, key);
     } else {
@@ -256,7 +258,7 @@ public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> {
 
   @Override
   public List<UpdateRequest> deleteNested(Object object, RuleKey key) {
-    Preconditions.checkArgument(key != null, "key of Rule must be set");
+    Preconditions.checkNotNull(key, "key of Rule must be set");
     if (object.getClass().isAssignableFrom(RuleParamDto.class)) {
       return nestedDelete((RuleParamDto) object, key);
     } else {
@@ -265,7 +267,6 @@ public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> {
   }
 
   private List<UpdateRequest> nestedUpdate(RuleParamDto param, RuleKey key) {
-
     Map<String, Object> newParam = new HashMap<String, Object>();
     newParam.put(RuleParamField.NAME.field(), param.getName());
     newParam.put(RuleParamField.TYPE.field(), param.getType());