}
public void insert(DbSession session, RuleDto dto) {
- mapper(session).insert(dto);
+ RuleDefinitionDto ruleDefinitionDto = definitionOf(dto);
+ mapper(session).insert(ruleDefinitionDto);
+ dto.setId(ruleDefinitionDto.getId());
+ // FIXME it doesn't make sense to insert metadata when creating a new rule in table RULES unless it is a custom rule
+ mapper(session).updateMetadata(metadataOf(dto));
}
public void update(DbSession session, RuleDto dto) {
- mapper(session).update(dto);
+ mapper(session).updateDefinition(definitionOf(dto).setId(dto.getId()));
+ RuleMetadataDto ruleMetadata = metadataOf(dto);
+ mapper(session).updateMetadata(ruleMetadata);
+ }
+
+ private static RuleMetadataDto metadataOf(RuleDto dto) {
+ return new RuleMetadataDto()
+ .setRuleId(dto.getId())
+ .setNoteData(dto.getNoteData())
+ .setNoteUserLogin(dto.getNoteUserLogin())
+ .setNoteCreatedAt(dto.getNoteCreatedAt())
+ .setNoteUpdatedAt(dto.getNoteUpdatedAt())
+ .setRemediationFunction(dto.getRemediationFunction())
+ .setRemediationGapMultiplier(dto.getRemediationGapMultiplier())
+ .setRemediationBaseEffort(dto.getRemediationBaseEffort())
+ .setTags(dto.getTags())
+ .setUpdatedAt(dto.getUpdatedAt());
+ }
+
+ private static RuleDefinitionDto definitionOf(RuleDto dto) {
+ return new RuleDefinitionDto()
+ .setRepositoryKey(dto.getRepositoryKey())
+ .setRuleKey(dto.getRuleKey())
+ .setDescription(dto.getDescription())
+ .setDescriptionFormat(dto.getDescriptionFormat())
+ .setStatus(dto.getStatus())
+ .setName(dto.getName())
+ .setConfigKey(dto.getConfigKey())
+ .setSeverity(dto.getSeverity())
+ .setIsTemplate(dto.isTemplate())
+ .setLanguage(dto.getLanguage())
+ .setTemplateId(dto.getTemplateId())
+ .setDefaultRemediationFunction(dto.getDefaultRemediationFunction())
+ .setDefaultRemediationGapMultiplier(dto.getDefaultRemediationGapMultiplier())
+ .setDefaultRemediationBaseEffort(dto.getDefaultRemediationBaseEffort())
+ .setGapDescription(dto.getGapDescription())
+ .setSystemTags(dto.getSystemTags())
+ .setType(dto.getType())
+ .setCreatedAt(dto.getCreatedAt())
+ .setUpdatedAt(dto.getUpdatedAt());
}
private static RuleMapper mapper(DbSession session) {
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.rule;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rules.RuleType;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class RuleDefinitionDto {
+
+ private Integer id;
+ private String repositoryKey;
+ private String ruleKey;
+ private String description;
+ private RuleDto.Format descriptionFormat;
+ private RuleStatus status;
+ private String name;
+ private String configKey;
+ private Integer severity;
+ private boolean isTemplate;
+ private String language;
+ private Integer templateId;
+ private String defRemediationFunction;
+ private String defRemediationGapMultiplier;
+ private String defRemediationBaseEffort;
+ private String gapDescription;
+ private String systemTags;
+ private int type;
+
+ private RuleKey key;
+
+ private long createdAt;
+ private long updatedAt;
+
+ public RuleKey getKey() {
+ if (key == null) {
+ key = RuleKey.of(getRepositoryKey(), getRuleKey());
+ }
+ return key;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public RuleDefinitionDto setId(Integer id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getRepositoryKey() {
+ return repositoryKey;
+ }
+
+ public RuleDefinitionDto setRepositoryKey(String s) {
+ checkArgument(s.length() <= 255, "Rule repository is too long: %s", s);
+ this.repositoryKey = s;
+ return this;
+ }
+
+ public String getRuleKey() {
+ return ruleKey;
+ }
+
+ public RuleDefinitionDto setRuleKey(String s) {
+ checkArgument(s.length() <= 200, "Rule key is too long: %s", s);
+ this.ruleKey = s;
+ return this;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public RuleDefinitionDto setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public RuleDto.Format getDescriptionFormat() {
+ return descriptionFormat;
+ }
+
+ public RuleDefinitionDto setDescriptionFormat(RuleDto.Format descriptionFormat) {
+ this.descriptionFormat = descriptionFormat;
+ return this;
+ }
+
+ public RuleStatus getStatus() {
+ return status;
+ }
+
+ public RuleDefinitionDto setStatus(@Nullable RuleStatus s) {
+ this.status = s;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public RuleDefinitionDto setName(@Nullable String s) {
+ checkArgument(s == null || s.length() <= 255, "Rule name is too long: %s", s);
+ this.name = s;
+ return this;
+ }
+
+ public String getConfigKey() {
+ return configKey;
+ }
+
+ public RuleDefinitionDto setConfigKey(@Nullable String configKey) {
+ this.configKey = configKey;
+ return this;
+ }
+
+ @CheckForNull
+ public Integer getSeverity() {
+ return severity;
+ }
+
+ @CheckForNull
+ public String getSeverityString() {
+ return severity != null ? SeverityUtil.getSeverityFromOrdinal(severity) : null;
+ }
+
+ public RuleDefinitionDto setSeverity(@Nullable String severity) {
+ return this.setSeverity(severity != null ? SeverityUtil.getOrdinalFromSeverity(severity) : null);
+ }
+
+ public RuleDefinitionDto setSeverity(@Nullable Integer severity) {
+ this.severity = severity;
+ return this;
+ }
+
+ public boolean isTemplate() {
+ return isTemplate;
+ }
+
+ public RuleDefinitionDto setIsTemplate(boolean isTemplate) {
+ this.isTemplate = isTemplate;
+ return this;
+ }
+
+ @CheckForNull
+ public String getLanguage() {
+ return language;
+ }
+
+ public RuleDefinitionDto setLanguage(String language) {
+ this.language = language;
+ return this;
+ }
+
+ @CheckForNull
+ public Integer getTemplateId() {
+ return templateId;
+ }
+
+ public RuleDefinitionDto setTemplateId(@Nullable Integer templateId) {
+ this.templateId = templateId;
+ return this;
+ }
+
+ @CheckForNull
+ public String getDefaultRemediationFunction() {
+ return defRemediationFunction;
+ }
+
+ public RuleDefinitionDto setDefaultRemediationFunction(@Nullable String defaultRemediationFunction) {
+ this.defRemediationFunction = defaultRemediationFunction;
+ return this;
+ }
+
+ @CheckForNull
+ public String getDefaultRemediationGapMultiplier() {
+ return defRemediationGapMultiplier;
+ }
+
+ public RuleDefinitionDto setDefaultRemediationGapMultiplier(@Nullable String defaultRemediationGapMultiplier) {
+ this.defRemediationGapMultiplier = defaultRemediationGapMultiplier;
+ return this;
+ }
+
+ @CheckForNull
+ public String getDefaultRemediationBaseEffort() {
+ return defRemediationBaseEffort;
+ }
+
+ public RuleDefinitionDto setDefaultRemediationBaseEffort(@Nullable String defaultRemediationBaseEffort) {
+ this.defRemediationBaseEffort = defaultRemediationBaseEffort;
+ return this;
+ }
+
+ @CheckForNull
+ public String getGapDescription() {
+ return gapDescription;
+ }
+
+ public RuleDefinitionDto setGapDescription(@Nullable String s) {
+ this.gapDescription = s;
+ return this;
+ }
+
+ public Set<String> getSystemTags() {
+ return systemTags == null ? new HashSet<>() : new TreeSet<>(Arrays.asList(StringUtils.split(systemTags, ',')));
+ }
+
+ private String getSystemTagsField() {
+ return systemTags;
+ }
+
+ private void setSystemTagsField(String s) {
+ systemTags = s;
+ }
+
+ public RuleDefinitionDto setSystemTags(Set<String> tags) {
+ this.systemTags = tags.isEmpty() ? null : StringUtils.join(tags, ',');
+ return this;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public RuleDefinitionDto setType(int type) {
+ this.type = type;
+ return this;
+ }
+
+ public RuleDefinitionDto setType(RuleType type) {
+ this.type = type.getDbConstant();
+ return this;
+ }
+
+ public long getCreatedAt() {
+ return createdAt;
+ }
+
+ public RuleDefinitionDto setCreatedAt(long createdAt) {
+ this.createdAt = createdAt;
+ return this;
+ }
+
+ public long getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public RuleDefinitionDto setUpdatedAt(long updatedAt) {
+ this.updatedAt = updatedAt;
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof RuleDto)) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ RuleDto other = (RuleDto) obj;
+ return new EqualsBuilder()
+ .append(repositoryKey, other.getRepositoryKey())
+ .append(ruleKey, other.getRuleKey())
+ .isEquals();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder(17, 37)
+ .append(repositoryKey)
+ .append(ruleKey)
+ .toHashCode();
+ }
+
+ @Override
+ public String toString() {
+ return new ReflectionToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).toString();
+ }
+
+ public static RuleDto createFor(RuleKey key) {
+ return new RuleDto()
+ .setRepositoryKey(key.repository())
+ .setRuleKey(key.rule());
+ }
+
+}
+
package org.sonar.db.rule;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
-import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import javax.annotation.CheckForNull;
}
public Set<String> getTags() {
- return tags == null ? new HashSet<>() : new TreeSet<>(Arrays.asList(StringUtils.split(tags, ',')));
+ return tags == null ? Collections.emptySet() : new TreeSet<>(Arrays.asList(StringUtils.split(tags, ',')));
}
public Set<String> getSystemTags() {
- return systemTags == null ? new HashSet<>() : new TreeSet<>(Arrays.asList(StringUtils.split(systemTags, ',')));
+ return systemTags == null ? Collections.emptySet() : new TreeSet<>(Arrays.asList(StringUtils.split(systemTags, ',')));
}
private String getTagsField() {
List<RuleDto> selectByQuery(@Param("query") RuleQuery ruleQuery);
- void update(RuleDto rule);
+ void insert(RuleDefinitionDto ruleDefinitionDto);
- void insert(RuleDto rule);
+ void updateDefinition(RuleDefinitionDto ruleDefinitionDto);
+
+ void updateMetadata(RuleMetadataDto ruleMetadataDto);
List<RuleParamDto> selectParamsByRuleIds(@Param("ruleIds") List<Integer> ruleIds);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.rule;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.StringUtils;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class RuleMetadataDto {
+ private int ruleId;
+ private String noteData;
+ private String noteUserLogin;
+ private Date noteCreatedAt;
+ private Date noteUpdatedAt;
+ private String remediationFunction;
+ private String remediationGapMultiplier;
+ private String remediationBaseEffort;
+ private String tags;
+ private long updatedAt;
+
+ public int getRuleId() {
+ return ruleId;
+ }
+
+ public RuleMetadataDto setRuleId(int ruleId) {
+ this.ruleId = ruleId;
+ return this;
+ }
+
+ @CheckForNull
+ public String getNoteData() {
+ return noteData;
+ }
+
+ public RuleMetadataDto setNoteData(@Nullable String s) {
+ this.noteData = s;
+ return this;
+ }
+
+ @CheckForNull
+ public String getNoteUserLogin() {
+ return noteUserLogin;
+ }
+
+ public RuleMetadataDto setNoteUserLogin(@Nullable String noteUserLogin) {
+ this.noteUserLogin = noteUserLogin;
+ return this;
+ }
+
+ @CheckForNull
+ public Date getNoteCreatedAt() {
+ return noteCreatedAt;
+ }
+
+ public RuleMetadataDto setNoteCreatedAt(@Nullable Date noteCreatedAt) {
+ this.noteCreatedAt = noteCreatedAt;
+ return this;
+ }
+
+ @CheckForNull
+ public Date getNoteUpdatedAt() {
+ return noteUpdatedAt;
+ }
+
+ public RuleMetadataDto setNoteUpdatedAt(@Nullable Date noteUpdatedAt) {
+ this.noteUpdatedAt = noteUpdatedAt;
+ return this;
+ }
+
+ @CheckForNull
+ public String getRemediationFunction() {
+ return remediationFunction;
+ }
+
+ public RuleMetadataDto setRemediationFunction(@Nullable String remediationFunction) {
+ this.remediationFunction = remediationFunction;
+ return this;
+ }
+
+ @CheckForNull
+ public String getRemediationGapMultiplier() {
+ return remediationGapMultiplier;
+ }
+
+ public RuleMetadataDto setRemediationGapMultiplier(@Nullable String remediationGapMultiplier) {
+ this.remediationGapMultiplier = remediationGapMultiplier;
+ return this;
+ }
+
+ @CheckForNull
+ public String getRemediationBaseEffort() {
+ return remediationBaseEffort;
+ }
+
+ public RuleMetadataDto setRemediationBaseEffort(@Nullable String remediationBaseEffort) {
+ this.remediationBaseEffort = remediationBaseEffort;
+ return this;
+ }
+
+ public Set<String> getTags() {
+ return tags == null ? new HashSet<>() : new TreeSet<>(Arrays.asList(StringUtils.split(tags, ',')));
+ }
+
+ public RuleMetadataDto setTags(Set<String> tags) {
+ String raw = tags.isEmpty() ? null : StringUtils.join(tags, ',');
+ checkArgument(raw == null || raw.length() <= 4000, "Rule tags are too long: %s", raw);
+ this.tags = raw;
+ return this;
+ }
+
+ private String getTagsField() {
+ return tags;
+ }
+
+ private void setTagsField(String s) {
+ tags = s;
+ }
+
+ public long getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public RuleMetadataDto setUpdatedAt(long updatedAt) {
+ this.updatedAt = updatedAt;
+ return this;
+ }
+}
r.updated_at desc
</select>
- <update id="update" parameterType="Rule">
- update rules set
- plugin_rule_key=#{ruleKey,jdbcType=VARCHAR},
- plugin_name=#{repositoryKey,jdbcType=VARCHAR},
- description=#{description,jdbcType=VARCHAR},
- description_format=#{descriptionFormat,jdbcType=VARCHAR},
- status=#{status,jdbcType=VARCHAR},
- name=#{name,jdbcType=VARCHAR},
- plugin_config_key=#{configKey,jdbcType=VARCHAR},
- priority=#{severity,jdbcType=INTEGER},
- is_template=#{isTemplate,jdbcType=BOOLEAN},
- language=#{language,jdbcType=VARCHAR},
- template_id=#{templateId,jdbcType=INTEGER},
- note_data=#{noteData,jdbcType=CLOB},
- note_user_login=#{noteUserLogin,jdbcType=VARCHAR},
- note_created_at=#{noteCreatedAt,jdbcType=TIMESTAMP},
- note_updated_at=#{noteUpdatedAt,jdbcType=TIMESTAMP},
- remediation_function=#{remediationFunction,jdbcType=VARCHAR},
- def_remediation_function=#{defRemediationFunction,jdbcType=VARCHAR},
- remediation_gap_mult=#{remediationGapMultiplier,jdbcType=VARCHAR},
- def_remediation_gap_mult=#{defRemediationGapMultiplier,jdbcType=VARCHAR},
- remediation_base_effort=#{remediationBaseEffort,jdbcType=VARCHAR},
- def_remediation_base_effort=#{defRemediationBaseEffort,jdbcType=VARCHAR},
- gap_description=#{gapDescription,jdbcType=VARCHAR},
- tags=#{tagsField,jdbcType=VARCHAR},
- system_tags=#{systemTagsField,jdbcType=VARCHAR},
- rule_type=#{type,jdbcType=TINYINT},
- updated_at=#{updatedAt,jdbcType=BIGINT}
- where
- id=#{id,jdbcType=INTEGER}
- </update>
-
- <insert id="insert" parameterType="Rule" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
+ <insert id="insert" parameterType="org.sonar.db.rule.RuleDefinitionDto" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
insert into rules (
plugin_rule_key,
plugin_name,
is_template,
language,
template_id,
- remediation_function,
def_remediation_function,
- remediation_gap_mult,
def_remediation_gap_mult,
- remediation_base_effort,
def_remediation_base_effort,
gap_description,
- tags,
system_tags,
rule_type,
- note_data,
- note_user_login,
- note_created_at,
- note_updated_at,
created_at,
updated_at
)
#{isTemplate,jdbcType=BOOLEAN},
#{language,jdbcType=VARCHAR},
#{templateId,jdbcType=INTEGER},
- #{remediationFunction,jdbcType=VARCHAR},
#{defRemediationFunction,jdbcType=VARCHAR},
- #{remediationGapMultiplier,jdbcType=VARCHAR},
#{defRemediationGapMultiplier,jdbcType=VARCHAR},
- #{remediationBaseEffort,jdbcType=VARCHAR},
#{defRemediationBaseEffort,jdbcType=VARCHAR},
#{gapDescription,jdbcType=VARCHAR},
- #{tagsField,jdbcType=VARCHAR},
#{systemTagsField,jdbcType=VARCHAR},
#{type,jdbcType=TINYINT},
- #{noteData,jdbcType=CLOB},
- #{noteUserLogin,jdbcType=VARCHAR},
- #{noteCreatedAt,jdbcType=TIMESTAMP},
- #{noteUpdatedAt,jdbcType=TIMESTAMP},
#{createdAt,jdbcType=BIGINT},
#{updatedAt,jdbcType=BIGINT}
)
</insert>
+ <update id="updateDefinition" parameterType="org.sonar.db.rule.RuleDefinitionDto">
+ update rules set
+ plugin_rule_key=#{ruleKey,jdbcType=VARCHAR},
+ plugin_name=#{repositoryKey,jdbcType=VARCHAR},
+ description=#{description,jdbcType=VARCHAR},
+ description_format=#{descriptionFormat,jdbcType=VARCHAR},
+ status=#{status,jdbcType=VARCHAR},
+ name=#{name,jdbcType=VARCHAR},
+ plugin_config_key=#{configKey,jdbcType=VARCHAR},
+ priority=#{severity,jdbcType=INTEGER},
+ is_template=#{isTemplate,jdbcType=BOOLEAN},
+ language=#{language,jdbcType=VARCHAR},
+ template_id=#{templateId,jdbcType=INTEGER},
+ def_remediation_function=#{defRemediationFunction,jdbcType=VARCHAR},
+ def_remediation_gap_mult=#{defRemediationGapMultiplier,jdbcType=VARCHAR},
+ def_remediation_base_effort=#{defRemediationBaseEffort,jdbcType=VARCHAR},
+ gap_description=#{gapDescription,jdbcType=VARCHAR},
+ system_tags=#{systemTagsField,jdbcType=VARCHAR},
+ rule_type=#{type,jdbcType=TINYINT},
+ updated_at=#{updatedAt,jdbcType=BIGINT}
+ where
+ id=#{id,jdbcType=INTEGER}
+ </update>
+
+ <update id="updateMetadata" parameterType="org.sonar.db.rule.RuleMetadataDto">
+ update rules set
+ note_data=#{noteData,jdbcType=CLOB},
+ note_user_login=#{noteUserLogin,jdbcType=VARCHAR},
+ note_created_at=#{noteCreatedAt,jdbcType=TIMESTAMP},
+ note_updated_at=#{noteUpdatedAt,jdbcType=TIMESTAMP},
+ remediation_function=#{remediationFunction,jdbcType=VARCHAR},
+ remediation_gap_mult=#{remediationGapMultiplier,jdbcType=VARCHAR},
+ remediation_base_effort=#{remediationBaseEffort,jdbcType=VARCHAR},
+ tags=#{tagsField,jdbcType=VARCHAR},
+ updated_at=#{updatedAt,jdbcType=BIGINT}
+ where
+ id=#{ruleId,jdbcType=INTEGER}
+ </update>
+
<delete id="deleteParams" parameterType="Integer">
delete from
active_rule_parameters
<dataset>
- <rules tags="[null]" system_tags="[null]" id="1" plugin_rule_key="AvoidNull" plugin_name="checkstyle"
- name="Avoid Null" description="Should avoid NULL" status="READY"
- plugin_config_key="AvoidNull" priority="2" is_template="[false]" language="golo"
- created_at="1500000000000" updated_at="1600000000000"/>
+ <rules tags="[null]"
+ system_tags="[null]"
+ id="1"
+ plugin_rule_key="AvoidNull"
+ plugin_name="checkstyle"
+ name="Avoid Null"
+ description="Should avoid NULL"
+ status="READY"
+ plugin_config_key="AvoidNull"
+ priority="2"
+ is_template="[false]"
+ language="golo"
+ created_at="1500000000000"
+ updated_at="1600000000000"/>
</dataset>