Browse Source

SONAR-906 new batch API for getting activated rules (merge of all the Quality profiles enabled on the project)

tags/4.2
Simon Brandhof 10 years ago
parent
commit
7cae10f6f1
34 changed files with 1264 additions and 85 deletions
  1. 23
    0
      sonar-batch/src/main/java/org/sonar/batch/rule/package-info.java
  2. 42
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ModuleRule.java
  3. 42
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ModuleRules.java
  4. 55
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Rule.java
  5. 32
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/RuleParam.java
  6. 42
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Rules.java
  7. 61
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultModuleRule.java
  8. 69
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultModuleRules.java
  9. 102
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRule.java
  10. 45
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRuleParam.java
  11. 69
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java
  12. 49
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/ModuleRulesBuilder.java
  13. 52
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewModuleRule.java
  14. 84
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewRule.java
  15. 36
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewRuleParam.java
  16. 50
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/RulesBuilder.java
  17. 23
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/package-info.java
  18. 23
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/package-info.java
  19. 31
    0
      sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleStatus.java
  20. 3
    0
      sonar-plugin-api/src/main/java/org/sonar/api/rule/Severity.java
  21. 53
    48
      sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitions.java
  22. 3
    2
      sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromAnnotations.java
  23. 4
    3
      sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromXml.java
  24. 83
    0
      sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ModuleRulesBuilderTest.java
  25. 111
    0
      sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/RulesBuilderTest.java
  26. 31
    0
      sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleStatusTest.java
  27. 4
    1
      sonar-plugin-api/src/test/java/org/sonar/api/rule/SeverityTest.java
  28. 4
    7
      sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsFromAnnotationsTest.java
  29. 6
    6
      sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest.java
  30. 19
    8
      sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsTest.java
  31. 3
    2
      sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRuleDefinitions.java
  32. 2
    2
      sonar-server/src/main/java/org/sonar/server/rule/RuleRegistration.java
  33. 3
    2
      sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRuleDefinitionsTest.java
  34. 5
    4
      sonar-server/src/test/java/org/sonar/server/rule/RuleRegistrationTest.java

+ 23
- 0
sonar-batch/src/main/java/org/sonar/batch/rule/package-info.java View File

@@ -0,0 +1,23 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2013 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.batch.rule;

import javax.annotation.ParametersAreNonnullByDefault;

+ 42
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ModuleRule.java View File

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

import org.sonar.api.rule.RuleKey;

import javax.annotation.CheckForNull;
import java.io.Serializable;
import java.util.Map;

/**
* @since 4.2
*/
public interface ModuleRule {

RuleKey ruleKey();

String severity();

@CheckForNull
String param(String key);

Map<String, String> params();

}

+ 42
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ModuleRules.java View File

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

import org.sonar.api.rule.RuleKey;

import javax.annotation.CheckForNull;
import java.util.Collection;

/**
* @since 4.2
*/
public interface ModuleRules {

@CheckForNull
ModuleRule find(RuleKey ruleKey);

/**
* All the rules that are enabled, whatever their repository and related language.
*/
Collection<ModuleRule> findAll();

Collection<ModuleRule> findByRepository(String repository);

}

+ 55
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Rule.java View File

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

import com.google.common.annotations.Beta;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;

import javax.annotation.CheckForNull;
import java.util.Collection;

/**
* Not used
* @since 4.2
*/
@Beta
public interface Rule {

RuleKey key();

String name();

@CheckForNull
String description();

@CheckForNull
String metadata();

String severity();

@CheckForNull
RuleParam param(String paramKey);

Collection<RuleParam> params();

RuleStatus status();

}

+ 32
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/RuleParam.java View File

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

import com.google.common.annotations.Beta;

/**
* Not used
* @since 4.2
*/
@Beta
public interface RuleParam {
String key();
String description();
}

+ 42
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Rules.java View File

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

import com.google.common.annotations.Beta;
import org.sonar.api.rule.RuleKey;

import javax.annotation.CheckForNull;
import java.util.Collection;

/**
* Not used
* @since 4.2
*/
@Beta
public interface Rules {

@CheckForNull
Rule find(RuleKey key);

Collection<Rule> findAll();

Collection<Rule> findByRepository(String repository);

}

+ 61
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultModuleRule.java View File

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

import com.google.common.collect.ImmutableMap;
import org.sonar.api.batch.rule.ModuleRule;
import org.sonar.api.rule.RuleKey;

import javax.annotation.concurrent.Immutable;
import java.util.Map;

@Immutable
class DefaultModuleRule implements ModuleRule {
private final RuleKey ruleKey;
private final String severity;
private final Map<String, String> params;

DefaultModuleRule(NewModuleRule newModuleRule) {
this.severity = newModuleRule.severity;
this.ruleKey = newModuleRule.ruleKey;
this.params = ImmutableMap.copyOf(newModuleRule.params);
}

@Override
public RuleKey ruleKey() {
return ruleKey;
}

@Override
public String severity() {
return severity;
}

@Override
public String param(String key) {
return params.get(key);
}

@Override
public Map<String, String> params() {
// immutable
return params;
}
}

+ 69
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultModuleRules.java View File

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

import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.rule.ModuleRule;
import org.sonar.api.batch.rule.ModuleRules;
import org.sonar.api.rule.RuleKey;

import javax.annotation.concurrent.Immutable;
import java.util.Collection;
import java.util.List;

@Immutable
class DefaultModuleRules implements ModuleRules {

// TODO use disk-backed cache (persistit) instead of full in-memory cache ?
private final ListMultimap<String, ModuleRule> moduleRulesByRepository;

public DefaultModuleRules(Collection<NewModuleRule> newModuleRules) {
ImmutableListMultimap.Builder<String, ModuleRule> builder = ImmutableListMultimap.builder();
for (NewModuleRule newMr : newModuleRules) {
DefaultModuleRule mr = new DefaultModuleRule(newMr);
builder.put(mr.ruleKey().repository(), mr);
}
moduleRulesByRepository = builder.build();
}


@Override
public ModuleRule find(RuleKey ruleKey) {
List<ModuleRule> rules = moduleRulesByRepository.get(ruleKey.repository());
for (ModuleRule rule : rules) {
if (StringUtils.equals(rule.ruleKey().rule(), ruleKey.rule())) {
return rule;
}
}
return null;
}

@Override
public Collection<ModuleRule> findAll() {
return moduleRulesByRepository.values();
}

@Override
public Collection<ModuleRule> findByRepository(String repository) {
return moduleRulesByRepository.get(repository);
}
}

+ 102
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRule.java View File

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

import com.google.common.collect.ImmutableMap;
import org.sonar.api.batch.rule.Rule;
import org.sonar.api.batch.rule.RuleParam;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;

import javax.annotation.CheckForNull;
import javax.annotation.concurrent.Immutable;
import java.util.Collection;
import java.util.Map;

@Immutable
public class DefaultRule implements Rule {

private final RuleKey key;
private Integer id;
private final String name, severity, description, metadata;
private final RuleStatus status;
private final Map<String, RuleParam> params;

DefaultRule(NewRule newRule) {
this.key = newRule.key;
this.id = newRule.id;
this.name = newRule.name;
this.severity = newRule.severity;
this.description = newRule.description;
this.metadata = newRule.metadata;
this.status = newRule.status;

ImmutableMap.Builder<String, RuleParam> builder = ImmutableMap.builder();
for (NewRuleParam newRuleParam : newRule.params.values()) {
builder.put(newRuleParam.key, new DefaultRuleParam(newRuleParam));
}
params = builder.build();
}

@Override
public RuleKey key() {
return key;
}

@CheckForNull
public Integer id() {
return id;
}

@Override
public String name() {
return name;
}

@Override
public String severity() {
return severity;
}

@Override
public String description() {
return description;
}

@Override
public String metadata() {
return metadata;
}

@Override
public RuleStatus status() {
return status;
}

@Override
public RuleParam param(String paramKey) {
return params.get(paramKey);
}

@Override
public Collection<RuleParam> params() {
return params.values();
}
}

+ 45
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRuleParam.java View File

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

import org.sonar.api.batch.rule.RuleParam;

import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

@Immutable
class DefaultRuleParam implements RuleParam {

private final String key, description;

DefaultRuleParam(NewRuleParam p) {
this.key = p.key;
this.description = p.description;
}

public String key() {
return key;
}

@Nullable
public String description() {
return description;
}
}

+ 69
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java View File

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

import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.rule.Rule;
import org.sonar.api.batch.rule.Rules;
import org.sonar.api.rule.RuleKey;

import javax.annotation.concurrent.Immutable;
import java.util.Collection;
import java.util.List;

@Immutable
class DefaultRules implements Rules {

// TODO use disk-backed cache (persistit) instead of full in-memory cache ?
private final ListMultimap<String, Rule> rulesByRepository;

DefaultRules(Collection<NewRule> newRules) {
ImmutableListMultimap.Builder<String, Rule> builder = ImmutableListMultimap.builder();
for (NewRule newRule : newRules) {
DefaultRule r = new DefaultRule(newRule);
builder.put(r.key().repository(), r);
}
rulesByRepository = builder.build();
}


@Override
public Rule find(RuleKey ruleKey) {
List<Rule> rules = rulesByRepository.get(ruleKey.repository());
for (Rule rule : rules) {
if (StringUtils.equals(rule.key().rule(), ruleKey.rule())) {
return rule;
}
}
return null;
}

@Override
public Collection<Rule> findAll() {
return rulesByRepository.values();
}

@Override
public Collection<Rule> findByRepository(String repository) {
return rulesByRepository.get(repository);
}
}

+ 49
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/ModuleRulesBuilder.java View File

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

import org.sonar.api.batch.rule.ModuleRules;
import org.sonar.api.rule.RuleKey;

import java.util.HashMap;
import java.util.Map;

/**
* For unit testing and internal use only.
*
* @since 4.2
*/
public class ModuleRulesBuilder {

private final Map<RuleKey, NewModuleRule> map = new HashMap<RuleKey, NewModuleRule>();

public NewModuleRule activate(RuleKey ruleKey) {
if (map.containsKey(ruleKey)) {
throw new IllegalStateException(String.format("Rule '%s' is already activated", ruleKey));
}
NewModuleRule newModuleRule = new NewModuleRule(ruleKey);
map.put(ruleKey, newModuleRule);
return newModuleRule;
}

public ModuleRules build() {
return new DefaultModuleRules(map.values());
}
}

+ 52
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewModuleRule.java View File

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

import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;

import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;

class NewModuleRule {
final RuleKey ruleKey;
String severity = Severity.defaultSeverity();
Map<String, String> params = new HashMap<String, String>();

public NewModuleRule(RuleKey ruleKey) {
this.ruleKey = ruleKey;
}

public NewModuleRule setSeverity(String severity) {
this.severity = severity;
return this;
}

public NewModuleRule setParam(String key, @Nullable String value) {
// possible improvement : check that the param key exists in rule definition
if (value == null) {
params.remove(key);
} else {
params.put(key, value);
}
return this;
}
}

+ 84
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewRule.java View File

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

import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.rule.RuleStatus;

import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;

public class NewRule {

private static final String DEFAULT_SEVERITY = Severity.defaultSeverity();

final RuleKey key;
Integer id;
String name, description, severity = DEFAULT_SEVERITY, metadata;
RuleStatus status = RuleStatus.defaultStatus();
Map<String, NewRuleParam> params = new HashMap<String, NewRuleParam>();

NewRule(RuleKey key) {
this.key = key;
}

public NewRule setId(@Nullable Integer id) {
this.id = id;
return this;
}

public NewRule setDescription(@Nullable String description) {
this.description = description;
return this;
}

public NewRule setName(@Nullable String s) {
this.name = s;
return this;
}

public NewRule setSeverity(@Nullable String severity) {
this.severity = StringUtils.defaultIfBlank(severity, DEFAULT_SEVERITY);
return this;
}

public NewRule setStatus(@Nullable RuleStatus s) {
this.status = (RuleStatus)ObjectUtils.defaultIfNull(s, RuleStatus.defaultStatus());
return this;
}

public NewRule setMetadata(@Nullable String metadata) {
this.metadata = metadata;
return this;
}

public NewRuleParam addParam(String paramKey) {
if (params.containsKey(paramKey)) {
throw new IllegalStateException(String.format("Parameter '%s' already exists on rule '%s'", paramKey, key));
}
NewRuleParam param = new NewRuleParam(paramKey);
params.put(paramKey, param);
return param;
}
}

+ 36
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewRuleParam.java View File

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

import javax.annotation.Nullable;

public class NewRuleParam {
final String key;
String description;

NewRuleParam(String key) {
this.key = key;
}

public NewRuleParam setDescription(@Nullable String s) {
description = s;
return this;
}
}

+ 50
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/RulesBuilder.java View File

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

import org.sonar.api.batch.rule.Rules;
import org.sonar.api.rule.RuleKey;

import java.util.HashMap;
import java.util.Map;

/**
* For unit testing and internal use only.
*
* @since 4.2
*/

public class RulesBuilder {

private final Map<RuleKey, NewRule> map = new HashMap<RuleKey, NewRule>();

public NewRule add(RuleKey key) {
if (map.containsKey(key)) {
throw new IllegalStateException(String.format("Rule '%s' already exists", key));
}
NewRule newRule = new NewRule(key);
map.put(key, newRule);
return newRule;
}

public Rules build() {
return new DefaultRules(map.values());
}
}

+ 23
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/package-info.java View File

@@ -0,0 +1,23 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2013 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.api.batch.rule.internal;

import javax.annotation.ParametersAreNonnullByDefault;

+ 23
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/package-info.java View File

@@ -0,0 +1,23 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2013 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.api.batch.rule;

import javax.annotation.ParametersAreNonnullByDefault;

+ 31
- 0
sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleStatus.java View File

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

/**
* @since 4.2
*/
public enum RuleStatus {
BETA, DEPRECATED, READY, REMOVED;

public static RuleStatus defaultStatus() {
return READY;
}
}

+ 3
- 0
sonar-plugin-api/src/main/java/org/sonar/api/rule/Severity.java View File

@@ -43,4 +43,7 @@ public final class Severity {
// utility
}

public static String defaultSeverity() {
return MAJOR;
}
}

+ 53
- 48
sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitions.java View File

@@ -24,9 +24,11 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.LoggerFactory;
import org.sonar.api.ServerExtension;
import org.sonar.api.rule.Severity;
import org.sonar.api.rule.RuleStatus;

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
@@ -97,38 +99,38 @@ public interface RuleDefinitions extends ServerExtension {
/**
* Reads definitions of rules from a XML file. Format is :
* <pre>
&lt;rules&gt;
&lt;rule&gt;
&lt;!-- required fields --&gt;
&lt;key&gt;the-rule-key&lt;/key&gt;
&lt;name&gt;The purpose of the rule&lt;/name&gt;
&lt;description&gt;
&lt;![CDATA[The description]]&gt;
&lt;/description&gt;
&lt;!-- optional fields --&gt;
&lt;configKey&gt;Checker/TreeWalker/LocalVariableName&lt;/configKey&gt;
&lt;severity&gt;BLOCKER&lt;/severity&gt;
&lt;cardinality&gt;MULTIPLE&lt;/cardinality&gt;
&lt;status&gt;BETA&lt;/status&gt;
&lt;param&gt;
&lt;key&gt;the-param-key&lt;/key&gt;
&lt;description&gt;
&lt;![CDATA[
the param-description
]]&gt;
&lt;/description&gt;
&lt;defaultValue&gt;42&lt;/defaultValue&gt;
&lt;/param&gt;
&lt;param&gt;
&lt;key&gt;another-param&lt;/key&gt;
&lt;/param&gt;
&lt;!-- deprecated fields --&gt;
&lt;priority&gt;BLOCKER&lt;/priority&gt;
&lt;/rule&gt;
&lt;/rules&gt;
* &lt;rules&gt;
* &lt;rule&gt;
* &lt;!-- required fields --&gt;
* &lt;key&gt;the-rule-key&lt;/key&gt;
* &lt;name&gt;The purpose of the rule&lt;/name&gt;
* &lt;description&gt;
* &lt;![CDATA[The description]]&gt;
* &lt;/description&gt;
*
* &lt;!-- optional fields --&gt;
* &lt;configKey&gt;Checker/TreeWalker/LocalVariableName&lt;/configKey&gt;
* &lt;severity&gt;BLOCKER&lt;/severity&gt;
* &lt;cardinality&gt;MULTIPLE&lt;/cardinality&gt;
* &lt;status&gt;BETA&lt;/status&gt;
* &lt;param&gt;
* &lt;key&gt;the-param-key&lt;/key&gt;
* &lt;description&gt;
* &lt;![CDATA[
* the param-description
* ]]&gt;
* &lt;/description&gt;
* &lt;defaultValue&gt;42&lt;/defaultValue&gt;
* &lt;/param&gt;
* &lt;param&gt;
* &lt;key&gt;another-param&lt;/key&gt;
* &lt;/param&gt;
*
* &lt;!-- deprecated fields --&gt;
* &lt;priority&gt;BLOCKER&lt;/priority&gt;
* &lt;/rule&gt;
* &lt;/rules&gt;
*
* </pre>
*/
void loadXml(InputStream xmlInput, String encoding);
@@ -214,6 +216,7 @@ public interface RuleDefinitions extends ServerExtension {
String name();
}

@Immutable
class RepositoryImpl implements Repository {
private final String key, language, name;
private final Map<String, Rule> rulesByKey;
@@ -277,9 +280,9 @@ public interface RuleDefinitions extends ServerExtension {

class NewRule {
private final String repoKey, key;
private String name, htmlDescription, metadata, defaultSeverity = Severity.MAJOR;
private String name, htmlDescription, metadata, severity = Severity.MAJOR;
private boolean template;
private Status status = Status.READY;
private RuleStatus status = RuleStatus.defaultStatus();
private final Set<String> tags = Sets.newTreeSet();
private final Map<String, NewParam> paramsByKey = Maps.newHashMap();

@@ -289,6 +292,7 @@ public interface RuleDefinitions extends ServerExtension {
}

public NewRule setName(String s) {
// TODO remove newlines
this.name = s;
return this;
}
@@ -298,11 +302,11 @@ public interface RuleDefinitions extends ServerExtension {
return this;
}

public NewRule setDefaultSeverity(String s) {
public NewRule setSeverity(String s) {
if (!Severity.ALL.contains(s)) {
throw new IllegalArgumentException(String.format("Default severity of rule %s is not correct: %s", this, s));
throw new IllegalArgumentException(String.format("Severity of rule %s is not correct: %s", this, s));
}
this.defaultSeverity = s;
this.severity = s;
return this;
}

@@ -311,7 +315,10 @@ public interface RuleDefinitions extends ServerExtension {
return this;
}

public NewRule setStatus(Status status) {
public NewRule setStatus(RuleStatus status) {
if (status.equals(RuleStatus.REMOVED)) {
throw new IllegalArgumentException(String.format("Status 'REMOVED' is not accepted on rule '%s'", this));
}
this.status = status;
return this;
}
@@ -370,17 +377,14 @@ public interface RuleDefinitions extends ServerExtension {
}
}

enum Status {
BETA, DEPRECATED, READY
}

@Immutable
class Rule {
private final Repository repository;
private final String repoKey, key, name, htmlDescription, metadata, defaultSeverity;
private final String repoKey, key, name, htmlDescription, metadata, severity;
private final boolean template;
private final Set<String> tags;
private final Map<String, Param> params;
private final Status status;
private final RuleStatus status;

private Rule(Repository repository, NewRule newRule) {
this.repository = repository;
@@ -389,7 +393,7 @@ public interface RuleDefinitions extends ServerExtension {
this.name = newRule.name;
this.htmlDescription = newRule.htmlDescription;
this.metadata = newRule.metadata;
this.defaultSeverity = newRule.defaultSeverity;
this.severity = newRule.severity;
this.template = newRule.template;
this.status = newRule.status;
this.tags = ImmutableSortedSet.copyOf(newRule.tags);
@@ -412,8 +416,8 @@ public interface RuleDefinitions extends ServerExtension {
return name;
}

public String defaultSeverity() {
return defaultSeverity;
public String severity() {
return severity;
}

@CheckForNull
@@ -425,7 +429,7 @@ public interface RuleDefinitions extends ServerExtension {
return template;
}

public Status status() {
public RuleStatus status() {
return status;
}

@@ -510,6 +514,7 @@ public interface RuleDefinitions extends ServerExtension {
}
}

@Immutable
class Param {
private final String key, name, description, defaultValue;
private final RuleParamType type;

+ 3
- 2
sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromAnnotations.java View File

@@ -26,6 +26,7 @@ import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.utils.AnnotationUtils;
import org.sonar.api.utils.FieldUtils2;
import org.sonar.check.Cardinality;
@@ -67,9 +68,9 @@ class RuleDefinitionsFromAnnotations {

RuleDefinitions.NewRule rule = repo.newRule(ruleKey);
rule.setName(ruleName).setHtmlDescription(description);
rule.setDefaultSeverity(ruleAnnotation.priority().name());
rule.setSeverity(ruleAnnotation.priority().name());
rule.setTemplate(ruleAnnotation.cardinality() == Cardinality.MULTIPLE);
rule.setStatus(RuleDefinitions.Status.valueOf(ruleAnnotation.status()));
rule.setStatus(RuleStatus.valueOf(ruleAnnotation.status()));

List<Field> fields = FieldUtils2.getFields(clazz, true);
for (Field field : fields) {

+ 4
- 3
sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromXml.java View File

@@ -25,6 +25,7 @@ import org.codehaus.staxmate.SMInputFactory;
import org.codehaus.staxmate.in.SMHierarchicCursor;
import org.codehaus.staxmate.in.SMInputCursor;
import org.sonar.api.rule.Severity;
import org.sonar.api.rule.RuleStatus;
import org.sonar.check.Cardinality;

import javax.xml.stream.XMLInputFactory;
@@ -79,7 +80,7 @@ class RuleDefinitionsFromXml {
}

private void processRule(RuleDefinitions.NewRepository repo, SMInputCursor ruleC) throws XMLStreamException {
String key = null, name = null, description = null, metadata = null, severity = Severity.MAJOR, status = null;
String key = null, name = null, description = null, metadata = null, severity = Severity.defaultSeverity(), status = null;
Cardinality cardinality = Cardinality.SINGLE;
List<ParamStruct> params = new ArrayList<ParamStruct>();

@@ -128,12 +129,12 @@ class RuleDefinitionsFromXml {
}
RuleDefinitions.NewRule rule = repo.newRule(key)
.setHtmlDescription(description)
.setDefaultSeverity(severity)
.setSeverity(severity)
.setName(name)
.setMetadata(metadata)
.setTemplate(cardinality == Cardinality.MULTIPLE);
if (status != null) {
rule.setStatus(RuleDefinitions.Status.valueOf(status));
rule.setStatus(RuleStatus.valueOf(status));
}
for (ParamStruct param : params) {
rule.newParam(param.key)

+ 83
- 0
sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ModuleRulesBuilderTest.java View File

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

import org.junit.Test;
import org.sonar.api.batch.rule.ModuleRule;
import org.sonar.api.batch.rule.ModuleRules;
import org.sonar.api.batch.rule.Rule;
import org.sonar.api.batch.rule.Rules;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;

import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;

public class ModuleRulesBuilderTest {
@Test
public void no_rules() throws Exception {
ModuleRulesBuilder builder = new ModuleRulesBuilder();
ModuleRules rules = builder.build();
assertThat(rules.findAll()).isEmpty();
}

@Test
public void build_rules() throws Exception {
ModuleRulesBuilder builder = new ModuleRulesBuilder();
NewModuleRule newSquid1 = builder.activate(RuleKey.of("squid", "S0001"));
newSquid1.setSeverity(Severity.CRITICAL);
newSquid1.setParam("min", "20");
// most simple rule
builder.activate(RuleKey.of("squid", "S0002"));
builder.activate(RuleKey.of("findbugs", "NPE"));

ModuleRules moduleRules = builder.build();

assertThat(moduleRules.findAll()).hasSize(3);
assertThat(moduleRules.findByRepository("squid")).hasSize(2);
assertThat(moduleRules.findByRepository("findbugs")).hasSize(1);
assertThat(moduleRules.findByRepository("unknown")).isEmpty();

ModuleRule squid1 = moduleRules.find(RuleKey.of("squid", "S0001"));
assertThat(squid1.ruleKey().repository()).isEqualTo("squid");
assertThat(squid1.ruleKey().rule()).isEqualTo("S0001");
assertThat(squid1.severity()).isEqualTo(Severity.CRITICAL);
assertThat(squid1.params()).hasSize(1);
assertThat(squid1.param("min")).isEqualTo("20");

ModuleRule squid2 = moduleRules.find(RuleKey.of("squid", "S0002"));
assertThat(squid2.ruleKey().repository()).isEqualTo("squid");
assertThat(squid2.ruleKey().rule()).isEqualTo("S0002");
assertThat(squid2.severity()).isEqualTo(Severity.defaultSeverity());
assertThat(squid2.params()).isEmpty();
}

@Test
public void fail_to_add_twice_the_same_rule() throws Exception {
ModuleRulesBuilder builder = new ModuleRulesBuilder();
builder.activate(RuleKey.of("squid", "S0001"));
try {
builder.activate(RuleKey.of("squid", "S0001"));
fail();
} catch (IllegalStateException e) {
assertThat(e).hasMessage("Rule 'squid:S0001' is already activated");
}
}
}

+ 111
- 0
sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/RulesBuilderTest.java View File

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

import org.junit.Test;
import org.sonar.api.batch.rule.Rule;
import org.sonar.api.batch.rule.Rules;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;

import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;

public class RulesBuilderTest {
@Test
public void no_rules() throws Exception {
RulesBuilder builder = new RulesBuilder();
Rules rules = builder.build();
assertThat(rules.findAll()).isEmpty();
}

@Test
public void build_rules() throws Exception {
RulesBuilder builder = new RulesBuilder();
NewRule newSquid1 = builder.add(RuleKey.of("squid", "S0001"));
newSquid1.setName("Detect bug");
newSquid1.setDescription("Detect potential bug");
newSquid1.setMetadata("foo=bar");
newSquid1.setSeverity(Severity.CRITICAL);
newSquid1.setStatus(RuleStatus.BETA);
newSquid1.addParam("min");
newSquid1.addParam("max").setDescription("Maximum");
// most simple rule
builder.add(RuleKey.of("squid", "S0002"));
builder.add(RuleKey.of("findbugs", "NPE"));

Rules rules = builder.build();

assertThat(rules.findAll()).hasSize(3);
assertThat(rules.findByRepository("squid")).hasSize(2);
assertThat(rules.findByRepository("findbugs")).hasSize(1);
assertThat(rules.findByRepository("unknown")).isEmpty();

Rule squid1 = rules.find(RuleKey.of("squid", "S0001"));
assertThat(squid1.key().repository()).isEqualTo("squid");
assertThat(squid1.key().rule()).isEqualTo("S0001");
assertThat(squid1.name()).isEqualTo("Detect bug");
assertThat(squid1.description()).isEqualTo("Detect potential bug");
assertThat(squid1.metadata()).isEqualTo("foo=bar");
assertThat(squid1.status()).isEqualTo(RuleStatus.BETA);
assertThat(squid1.severity()).isEqualTo(Severity.CRITICAL);
assertThat(squid1.params()).hasSize(2);
assertThat(squid1.param("min").key()).isEqualTo("min");
assertThat(squid1.param("min").description()).isNull();
assertThat(squid1.param("max").key()).isEqualTo("max");
assertThat(squid1.param("max").description()).isEqualTo("Maximum");

Rule squid2 = rules.find(RuleKey.of("squid", "S0002"));
assertThat(squid2.key().repository()).isEqualTo("squid");
assertThat(squid2.key().rule()).isEqualTo("S0002");
assertThat(squid2.description()).isNull();
assertThat(squid2.metadata()).isNull();
assertThat(squid2.status()).isEqualTo(RuleStatus.defaultStatus());
assertThat(squid2.severity()).isEqualTo(Severity.defaultSeverity());
assertThat(squid2.params()).isEmpty();
}

@Test
public void fail_to_add_twice_the_same_rule() throws Exception {
RulesBuilder builder = new RulesBuilder();
builder.add(RuleKey.of("squid", "S0001"));
try {
builder.add(RuleKey.of("squid", "S0001"));
fail();
} catch (IllegalStateException e) {
assertThat(e).hasMessage("Rule 'squid:S0001' already exists");
}
}

@Test
public void fail_to_add_twice_the_same_param() throws Exception {
RulesBuilder builder = new RulesBuilder();
NewRule newRule = builder.add(RuleKey.of("squid", "S0001"));
newRule.addParam("min");
newRule.addParam("max");
try {
newRule.addParam("min");
fail();
} catch (IllegalStateException e) {
assertThat(e).hasMessage("Parameter 'min' already exists on rule 'squid:S0001'");
}
}
}

+ 31
- 0
sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleStatusTest.java View File

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

import org.junit.Test;

import static org.fest.assertions.Assertions.assertThat;

public class RuleStatusTest {
@Test
public void default_is_ready() throws Exception {
assertThat(RuleStatus.defaultStatus()).isEqualTo(RuleStatus.READY);
}
}

+ 4
- 1
sonar-plugin-api/src/test/java/org/sonar/api/rule/SeverityTest.java View File

@@ -28,7 +28,10 @@ public class SeverityTest {
@Test
public void test_ALL() throws Exception {
assertThat(Severity.ALL).hasSize(5).containsSequence("INFO", "MINOR", "MAJOR", "CRITICAL", "BLOCKER");

}

@Test
public void default_is_major() throws Exception {
assertThat(Severity.defaultSeverity()).isEqualTo(Severity.MAJOR);
}
}

+ 4
- 7
sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsFromAnnotationsTest.java View File

@@ -23,9 +23,7 @@ import org.junit.Ignore;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.rule.Severity;
import org.sonar.api.server.rule.RuleDefinitions;
import org.sonar.api.server.rule.RuleDefinitionsFromAnnotations;
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.rule.RuleStatus;
import org.sonar.check.Priority;

import static org.fest.assertions.Assertions.assertThat;
@@ -41,11 +39,10 @@ public class RuleDefinitionsFromAnnotationsTest {
assertThat(repository.rules()).hasSize(1);
RuleDefinitions.Rule rule = repository.rules().get(0);
assertThat(rule.key()).isEqualTo("foo");
assertThat(rule.status()).isEqualTo(RuleDefinitions.Status.BETA);
assertThat(rule.status()).isEqualTo(RuleStatus.BETA);
assertThat(rule.name()).isEqualTo("bar");
assertThat(rule.htmlDescription()).isEqualTo("Foo Bar");
assertThat(rule.defaultSeverity()).isEqualTo(Severity.BLOCKER);
assertThat(rule.status()).isEqualTo(RuleDefinitions.Status.BETA);
assertThat(rule.severity()).isEqualTo(Severity.BLOCKER);
assertThat(rule.params()).hasSize(1);

RuleDefinitions.Param prop = rule.param("property");
@@ -112,7 +109,7 @@ public class RuleDefinitionsFromAnnotationsTest {
RuleDefinitions.Rule rule = repository.rules().get(0);
assertThat(rule.key()).isEqualTo("overriding_foo");
assertThat(rule.name()).isEqualTo("Overriding Foo");
assertThat(rule.defaultSeverity()).isEqualTo(Severity.MAJOR);
assertThat(rule.severity()).isEqualTo(Severity.MAJOR);
assertThat(rule.htmlDescription()).isEqualTo("Desc of Overriding Foo");
assertThat(rule.params()).hasSize(2);
}

+ 6
- 6
sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest.java View File

@@ -23,6 +23,7 @@ import com.google.common.base.Charsets;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.rule.Severity;
import org.sonar.api.rule.RuleStatus;

import java.io.InputStreamReader;
import java.io.Reader;
@@ -54,11 +55,10 @@ public class RuleDefinitionsFromXmlTest {
assertThat(rule.key()).isEqualTo("complete");
assertThat(rule.name()).isEqualTo("Complete");
assertThat(rule.htmlDescription()).isEqualTo("Description of Complete");
assertThat(rule.defaultSeverity()).isEqualTo(Severity.BLOCKER);
assertThat(rule.severity()).isEqualTo(Severity.BLOCKER);
assertThat(rule.template()).isTrue();
assertThat(rule.status()).isEqualTo(RuleDefinitions.Status.BETA);
assertThat(rule.status()).isEqualTo(RuleStatus.BETA);
assertThat(rule.metadata()).isEqualTo("Checker/TreeWalker/LocalVariableName");
assertThat(rule.status()).isEqualTo(RuleDefinitions.Status.BETA);

assertThat(rule.params()).hasSize(2);
RuleDefinitions.Param ignore = rule.param("ignore");
@@ -71,8 +71,8 @@ public class RuleDefinitionsFromXmlTest {
assertThat(rule.name()).isEqualTo("Minimal");
assertThat(rule.htmlDescription()).isEqualTo("Description of Minimal");
assertThat(rule.params()).isEmpty();
assertThat(rule.status()).isEqualTo(RuleDefinitions.Status.READY);
assertThat(rule.defaultSeverity()).isEqualTo(Severity.MAJOR);
assertThat(rule.status()).isEqualTo(RuleStatus.READY);
assertThat(rule.severity()).isEqualTo(Severity.MAJOR);
}

@Test
@@ -116,7 +116,7 @@ public class RuleDefinitionsFromXmlTest {
assertThat(repository.rules()).hasSize(1);
RuleDefinitions.Rule rule = repository.rules().get(0);
assertThat(rule.key()).isEqualTo("org.sonar.it.checkstyle.MethodsCountCheck");
assertThat(rule.defaultSeverity()).isEqualTo(Severity.CRITICAL);
assertThat(rule.severity()).isEqualTo(Severity.CRITICAL);
assertThat(rule.htmlDescription()).isEqualTo("Count methods");
assertThat(rule.param("minMethodsCount")).isNotNull();
}

+ 19
- 8
sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsTest.java View File

@@ -21,6 +21,7 @@ package org.sonar.api.server.rule;

import org.junit.Test;
import org.sonar.api.rule.Severity;
import org.sonar.api.rule.RuleStatus;

import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;
@@ -65,9 +66,9 @@ public class RuleDefinitionsTest {
.setName("Detect NPE")
.setHtmlDescription("Detect <code>NPE</code>")
.setHtmlDescription("Detect <code>java.lang.NullPointerException</code>")
.setDefaultSeverity(Severity.BLOCKER)
.setSeverity(Severity.BLOCKER)
.setMetadata("/something")
.setStatus(RuleDefinitions.Status.BETA)
.setStatus(RuleStatus.BETA)
.setTags("one", "two")
.addTags("two", "three", "four");
newFindbugs.newRule("ABC").setName("ABC").setHtmlDescription("ABC");
@@ -79,13 +80,13 @@ public class RuleDefinitionsTest {
RuleDefinitions.Rule npeRule = findbugs.rule("NPE");
assertThat(npeRule.key()).isEqualTo("NPE");
assertThat(npeRule.name()).isEqualTo("Detect NPE");
assertThat(npeRule.defaultSeverity()).isEqualTo(Severity.BLOCKER);
assertThat(npeRule.severity()).isEqualTo(Severity.BLOCKER);
assertThat(npeRule.htmlDescription()).isEqualTo("Detect <code>java.lang.NullPointerException</code>");
assertThat(npeRule.tags()).containsOnly("one", "two", "three", "four");
assertThat(npeRule.params()).isEmpty();
assertThat(npeRule.metadata()).isEqualTo("/something");
assertThat(npeRule.template()).isFalse();
assertThat(npeRule.status()).isEqualTo(RuleDefinitions.Status.BETA);
assertThat(npeRule.status()).isEqualTo(RuleStatus.BETA);
assertThat(npeRule.toString()).isEqualTo("[repository=findbugs, key=NPE]");
assertThat(npeRule.repository()).isSameAs(findbugs);

@@ -103,10 +104,10 @@ public class RuleDefinitionsTest {

RuleDefinitions.Rule rule = context.repository("findbugs").rule("NPE");
assertThat(rule.key()).isEqualTo("NPE");
assertThat(rule.defaultSeverity()).isEqualTo(Severity.MAJOR);
assertThat(rule.severity()).isEqualTo(Severity.MAJOR);
assertThat(rule.params()).isEmpty();
assertThat(rule.metadata()).isNull();
assertThat(rule.status()).isEqualTo(RuleDefinitions.Status.READY);
assertThat(rule.status()).isEqualTo(RuleStatus.defaultStatus());
assertThat(rule.tags()).isEmpty();
}

@@ -234,10 +235,20 @@ public class RuleDefinitionsTest {
@Test
public void fail_if_bad_rule_severity() {
try {
context.newRepository("findbugs", "java").newRule("NPE").setDefaultSeverity("VERY HIGH");
context.newRepository("findbugs", "java").newRule("NPE").setSeverity("VERY HIGH");
fail();
} catch (IllegalArgumentException e) {
assertThat(e).hasMessage("Default severity of rule [repository=findbugs, key=NPE] is not correct: VERY HIGH");
assertThat(e).hasMessage("Severity of rule [repository=findbugs, key=NPE] is not correct: VERY HIGH");
}
}

@Test
public void fail_if_removed_status() {
try {
context.newRepository("findbugs", "java").newRule("NPE").setStatus(RuleStatus.REMOVED);
fail();
} catch (IllegalArgumentException e) {
assertThat(e).hasMessage("Status 'REMOVED' is not accepted on rule '[repository=findbugs, key=NPE]'");
}
}
}

+ 3
- 2
sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRuleDefinitions.java View File

@@ -20,6 +20,7 @@
package org.sonar.server.rule;

import org.apache.commons.lang.StringUtils;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.server.rule.RuleDefinitions;
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.rules.RuleParam;
@@ -64,8 +65,8 @@ public class DeprecatedRuleDefinitions implements RuleDefinitions {
newRule.setHtmlDescription(ruleDescription(repository.getKey(), rule));
newRule.setMetadata(rule.getConfigKey());
newRule.setTemplate(Cardinality.MULTIPLE.equals(rule.getCardinality()));
newRule.setDefaultSeverity(rule.getSeverity().toString());
newRule.setStatus(rule.getStatus() == null ? Status.READY : Status.valueOf(rule.getStatus()));
newRule.setSeverity(rule.getSeverity().toString());
newRule.setStatus(rule.getStatus() == null ? RuleStatus.defaultStatus() : RuleStatus.valueOf(rule.getStatus()));
for (RuleParam param : rule.getParams()) {
NewParam newParam = newRule.newParam(param.getKey());
newParam.setDefaultValue(param.getDefaultValue());

+ 2
- 2
sonar-server/src/main/java/org/sonar/server/rule/RuleRegistration.java View File

@@ -155,7 +155,7 @@ public class RuleRegistration implements Startable {
.setName(ruleDef.name())
.setRepositoryKey(ruleDef.repository().key())
.setRuleKey(ruleDef.key())
.setSeverity(RulePriority.valueOf(ruleDef.defaultSeverity()).name())
.setSeverity(RulePriority.valueOf(ruleDef.severity()).name())
.setCreatedAt(buffer.now())
.setUpdatedAt(buffer.now())
.setStatus(ruleDef.status().name());
@@ -199,7 +199,7 @@ public class RuleRegistration implements Startable {
dto.setConfigKey(def.metadata());
changed = true;
}
String severity = RulePriority.valueOf(def.defaultSeverity()).name();
String severity = RulePriority.valueOf(def.severity()).name();
if (!ObjectUtils.equals(dto.getSeverityString(), severity)) {
dto.setSeverity(severity);
changed = true;

+ 3
- 2
sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRuleDefinitionsTest.java View File

@@ -20,6 +20,7 @@
package org.sonar.server.rule;

import org.junit.Test;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.server.rule.RuleDefinitions;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.Rule;
@@ -73,9 +74,9 @@ public class DeprecatedRuleDefinitionsTest {
assertThat(rule.key()).isEqualTo("ConstantName");
assertThat(rule.name()).isEqualTo("Constant Name");
assertThat(rule.htmlDescription()).isEqualTo("Checks that constant names conform to the specified format");
assertThat(rule.defaultSeverity()).isEqualTo(Severity.BLOCKER);
assertThat(rule.severity()).isEqualTo(Severity.BLOCKER);
assertThat(rule.metadata()).isEqualTo("Checker/TreeWalker/ConstantName");
assertThat(rule.status()).isEqualTo(RuleDefinitions.Status.BETA);
assertThat(rule.status()).isEqualTo(RuleStatus.BETA);
assertThat(rule.tags()).isEmpty();
assertThat(rule.params()).hasSize(1);
RuleDefinitions.Param param = rule.param("format");

+ 5
- 4
sonar-server/src/test/java/org/sonar/server/rule/RuleRegistrationTest.java View File

@@ -23,6 +23,7 @@ package org.sonar.server.rule;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.rule.Severity;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.server.rule.RuleDefinitions;
import org.sonar.core.persistence.AbstractDaoTestCase;
import org.sonar.core.persistence.MyBatis;
@@ -202,7 +203,7 @@ public class RuleRegistrationTest extends AbstractDaoTestCase {
NewRule rule1 = repo.newRule("rule1")
.setName("One")
.setHtmlDescription("Description of One")
.setDefaultSeverity(Severity.BLOCKER)
.setSeverity(Severity.BLOCKER)
.setMetadata("config1")
.setTags("tag1", "tag3", "tag5");
rule1.newParam("param1").setDescription("parameter one").setDefaultValue("default value one");
@@ -211,8 +212,8 @@ public class RuleRegistrationTest extends AbstractDaoTestCase {
repo.newRule("rule2")
.setName("Two")
.setHtmlDescription("Description of Two")
.setDefaultSeverity(Severity.INFO)
.setStatus(Status.DEPRECATED);
.setSeverity(Severity.INFO)
.setStatus(RuleStatus.DEPRECATED);
repo.done();
}
}
@@ -227,7 +228,7 @@ public class RuleRegistrationTest extends AbstractDaoTestCase {
NewRule rule = repo.newRule("rule" + i)
.setName("name of " + i)
.setHtmlDescription("description of " + i)
.setDefaultSeverity(Severity.BLOCKER)
.setSeverity(Severity.BLOCKER)
.setMetadata("config1")
.setTags("tag1", "tag3", "tag5");
for (int j = 0; j < 20; j++) {

Loading…
Cancel
Save