@@ -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; |
@@ -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(); | |||
} |
@@ -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); | |||
} |
@@ -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(); | |||
} |
@@ -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(); | |||
} |
@@ -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); | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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; |
@@ -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; |
@@ -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; | |||
} | |||
} |
@@ -43,4 +43,7 @@ public final class Severity { | |||
// utility | |||
} | |||
public static String defaultSeverity() { | |||
return MAJOR; | |||
} | |||
} |
@@ -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> | |||
<rules> | |||
<rule> | |||
<!-- required fields --> | |||
<key>the-rule-key</key> | |||
<name>The purpose of the rule</name> | |||
<description> | |||
<![CDATA[The description]]> | |||
</description> | |||
<!-- optional fields --> | |||
<configKey>Checker/TreeWalker/LocalVariableName</configKey> | |||
<severity>BLOCKER</severity> | |||
<cardinality>MULTIPLE</cardinality> | |||
<status>BETA</status> | |||
<param> | |||
<key>the-param-key</key> | |||
<description> | |||
<![CDATA[ | |||
the param-description | |||
]]> | |||
</description> | |||
<defaultValue>42</defaultValue> | |||
</param> | |||
<param> | |||
<key>another-param</key> | |||
</param> | |||
<!-- deprecated fields --> | |||
<priority>BLOCKER</priority> | |||
</rule> | |||
</rules> | |||
* <rules> | |||
* <rule> | |||
* <!-- required fields --> | |||
* <key>the-rule-key</key> | |||
* <name>The purpose of the rule</name> | |||
* <description> | |||
* <![CDATA[The description]]> | |||
* </description> | |||
* | |||
* <!-- optional fields --> | |||
* <configKey>Checker/TreeWalker/LocalVariableName</configKey> | |||
* <severity>BLOCKER</severity> | |||
* <cardinality>MULTIPLE</cardinality> | |||
* <status>BETA</status> | |||
* <param> | |||
* <key>the-param-key</key> | |||
* <description> | |||
* <![CDATA[ | |||
* the param-description | |||
* ]]> | |||
* </description> | |||
* <defaultValue>42</defaultValue> | |||
* </param> | |||
* <param> | |||
* <key>another-param</key> | |||
* </param> | |||
* | |||
* <!-- deprecated fields --> | |||
* <priority>BLOCKER</priority> | |||
* </rule> | |||
* </rules> | |||
* | |||
* </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; |
@@ -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) { |
@@ -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) |
@@ -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"); | |||
} | |||
} | |||
} |
@@ -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'"); | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} |
@@ -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(); | |||
} |
@@ -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]'"); | |||
} | |||
} | |||
} |
@@ -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()); |
@@ -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; |
@@ -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"); |
@@ -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++) { |