import org.sonar.server.computation.issue.NewDebtCalculator;
import org.sonar.server.computation.issue.RuleRepositoryImpl;
import org.sonar.server.computation.issue.RuleTagsCopier;
+import org.sonar.server.computation.issue.RuleTypeCopier;
import org.sonar.server.computation.issue.ScmAccountToUser;
import org.sonar.server.computation.issue.ScmAccountToUserLoader;
import org.sonar.server.computation.issue.TrackerBaseInputFactory;
NewDebtAggregator.class,
IssueAssigner.class,
RuleTagsCopier.class,
+ RuleTypeCopier.class,
IssueCounter.class,
// visitors : order is important, measure computers must be executed at the end in order to access to every measures / issues
public void mergeExistingOpenIssue(DefaultIssue raw, DefaultIssue base) {
raw.setNew(false);
raw.setKey(base.key());
+ raw.setType(base.type());
raw.setCreationDate(base.creationDate());
raw.setUpdateDate(base.updateDate());
raw.setCloseDate(base.closeDate());
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.server.debt.DebtRemediationFunction;
+import org.sonar.core.issue.IssueType;
public interface Rule {
RuleStatus getStatus();
+ IssueType getType();
+
/**
* Get all tags, whatever system or user tags.
*/
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.server.debt.DebtRemediationFunction;
import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction;
+import org.sonar.core.issue.IssueType;
import org.sonar.db.rule.RuleDto;
import static com.google.common.collect.Sets.union;
private final RuleStatus status;
private final Set<String> tags;
private final DebtRemediationFunction remediationFunction;
+ private final IssueType type;
public RuleImpl(RuleDto dto) {
this.id = dto.getId();
this.status = dto.getStatus();
this.tags = union(dto.getSystemTags(), dto.getTags());
this.remediationFunction = effectiveRemediationFunction(dto);
+ // TODO get rule type
+ this.type = IssueType.CODE_SMELL;
}
@Override
return remediationFunction;
}
+ @Override
+ public IssueType getType() {
+ return type;
+ }
+
@Override
public boolean equals(@Nullable Object o) {
if (this == o) {
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.server.computation.issue;
+
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.server.computation.component.Component;
+
+import static com.google.common.collect.Sets.union;
+
+public class RuleTypeCopier extends IssueVisitor {
+
+ private final RuleRepository ruleRepository;
+
+ public RuleTypeCopier(RuleRepository ruleRepository) {
+ this.ruleRepository = ruleRepository;
+ }
+
+ @Override
+ public void onIssue(Component component, DefaultIssue issue) {
+ if (issue.type()==null) {
+ Rule rule = ruleRepository.getByKey(issue.ruleKey());
+ issue.setType(rule.getType());
+ }
+ }
+}
private final Collection<String> authors;
private final Collection<String> languages;
private final Collection<String> tags;
+ private final Collection<String> types;
private final Boolean onComponentOnly;
private final Boolean assigned;
private final Boolean planned;
this.authors = defaultCollection(builder.authors);
this.languages = defaultCollection(builder.languages);
this.tags = defaultCollection(builder.tags);
+ this.types = defaultCollection(builder.types);
this.onComponentOnly = builder.onComponentOnly;
this.assigned = builder.assigned;
this.planned = builder.planned;
return tags;
}
+ public Collection<String> types() {
+ return types;
+ }
+
@CheckForNull
public Boolean onComponentOnly() {
return onComponentOnly;
private Collection<String> authors;
private Collection<String> languages;
private Collection<String> tags;
+ private Collection<String> types;
private Boolean onComponentOnly = false;
private Boolean assigned = null;
private Boolean planned = null;
return this;
}
+ public Builder types(@Nullable Collection<String> t) {
+ this.types = t;
+ return this;
+ }
+
/**
* If true, it will return only issues on the passed component(s)
* If false, it will return all issues on the passed component(s) and their descendants
.assignees(buildAssignees(RubyUtils.toStrings(params.get(IssueFilterParameters.ASSIGNEES))))
.languages(RubyUtils.toStrings(params.get(IssueFilterParameters.LANGUAGES)))
.tags(RubyUtils.toStrings(params.get(IssueFilterParameters.TAGS)))
+ .types(RubyUtils.toStrings(params.get(IssueFilterParameters.TYPES)))
.assigned(RubyUtils.toBoolean(params.get(IssueFilterParameters.ASSIGNED)))
.planned(RubyUtils.toBoolean(params.get(IssueFilterParameters.PLANNED)))
.hideRules(RubyUtils.toBoolean(params.get(IssueFilterParameters.HIDE_RULES)))
.assignees(buildAssignees(request.getAssignees()))
.languages(request.getLanguages())
.tags(request.getTags())
+ .types(request.getTypes())
.assigned(request.getAssigned())
.planned(request.getPlanned())
.createdAt(parseAsDateTime(request.getCreatedAt()))
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.DefaultIssueBuilder;
import org.sonar.core.issue.IssueChangeContext;
+import org.sonar.core.issue.IssueType;
import org.sonar.server.issue.workflow.IssueWorkflow;
import org.sonar.server.issue.workflow.Transition;
import org.sonar.db.DbClient;
return allowedTransitions;
}
- public Issue doTransition(String issueKey, String transitionKey) {
- verifyLoggedIn();
+ public void doTransition(String issueKey, String transitionKey) {
+ userSession.checkLoggedIn();
DbSession session = dbClient.openSession(false);
try {
if (workflow.doTransition(defaultIssue, transitionKey, context)) {
saveIssue(session, defaultIssue, context, null);
}
- return defaultIssue;
} finally {
session.close();
}
}
- public Issue assign(String issueKey, @Nullable String assignee) {
- verifyLoggedIn();
+ public void assign(String issueKey, @Nullable String assignee) {
+ userSession.checkLoggedIn();
DbSession session = dbClient.openSession(false);
try {
if (issueUpdater.assign(issue, user, context)) {
saveIssue(session, issue, context, null);
}
- return issue;
} finally {
session.close();
}
}
- public Issue plan(String issueKey, @Nullable String actionPlanKey) {
- verifyLoggedIn();
+ public void plan(String issueKey, @Nullable String actionPlanKey) {
+ userSession.checkLoggedIn();
DbSession session = dbClient.openSession(false);
try {
if (issueUpdater.plan(issue, actionPlan, context)) {
saveIssue(session, issue, context, null);
}
- return issue;
} finally {
session.close();
}
}
- public Issue setSeverity(String issueKey, String severity) {
- verifyLoggedIn();
+ public void setSeverity(String issueKey, String severity) {
+ userSession.checkLoggedIn();
DbSession session = dbClient.openSession(false);
try {
if (issueUpdater.setManualSeverity(issue, severity, context)) {
saveIssue(session, issue, context, null);
}
- return issue;
} finally {
session.close();
}
}
- public DefaultIssue createManualIssue(String componentKey, RuleKey ruleKey, @Nullable Integer line, @Nullable String message, @Nullable String severity) {
- verifyLoggedIn();
+ public Issue createManualIssue(String componentKey, RuleKey ruleKey, @Nullable Integer line, @Nullable String message, @Nullable String severity) {
+ userSession.checkLoggedIn();
DbSession dbSession = dbClient.openSession(false);
try {
DefaultIssue issue = new DefaultIssueBuilder()
.componentKey(component.getKey())
+ // TODO use rule type: type(rule.type())
.projectKey(project.getKey())
.line(line)
.message(!Strings.isNullOrEmpty(message) ? message : rule.getName())
return issueIndex.search(query, options);
}
- private void verifyLoggedIn() {
- userSession.checkLoggedIn();
- }
-
/**
* Search for all tags, whatever issue resolution or user access rights
*/
}
public Collection<String> setTags(String issueKey, Collection<String> tags) {
- verifyLoggedIn();
+ userSession.checkLoggedIn();
DbSession session = dbClient.openSession(false);
try {
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.Duration;
import org.sonar.api.utils.KeyValueFormat;
+import org.sonar.core.issue.IssueType;
import org.sonar.server.search.BaseDoc;
public class IssueDoc extends BaseDoc implements Issue {
return getNullableField(IssueIndexDefinition.FIELD_ISSUE_ACTION_PLAN);
}
+ @CheckForNull
+ public IssueType type() {
+ String type = getNullableField(IssueIndexDefinition.FIELD_ISSUE_TYPE);
+ if (type != null) {
+ return IssueType.valueOf(type);
+ }
+ return null;
+ }
+
@Override
public List<IssueComment> comments() {
throw new IllegalStateException("Comments are not availables in index");
setField(IssueIndexDefinition.FIELD_ISSUE_TAGS, tags);
return this;
}
+
+ public IssueDoc setType(IssueType type) {
+ setField(IssueIndexDefinition.FIELD_ISSUE_TYPE, type.toString());
+ return this;
+ }
}
IssueFilterParameters.DIRECTORIES,
IssueFilterParameters.LANGUAGES,
IssueFilterParameters.TAGS,
+ IssueFilterParameters.TYPES,
IssueFilterParameters.CREATED_AT);
// TODO to be documented
filters.put(IssueIndexDefinition.FIELD_ISSUE_LANGUAGE, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_LANGUAGE, query.languages()));
filters.put(IssueIndexDefinition.FIELD_ISSUE_TAGS, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_TAGS, query.tags()));
+ filters.put(IssueIndexDefinition.FIELD_ISSUE_TYPE, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_TYPE, query.types()));
filters.put(IssueIndexDefinition.FIELD_ISSUE_RESOLUTION, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_RESOLUTION, query.resolutions()));
filters.put(IssueIndexDefinition.FIELD_ISSUE_REPORTER, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_REPORTER, query.reporters()));
filters.put(IssueIndexDefinition.FIELD_ISSUE_AUTHOR_LOGIN, createTermsFilter(IssueIndexDefinition.FIELD_ISSUE_AUTHOR_LOGIN, query.authors()));
if (options.getFacets().contains(IssueFilterParameters.TAGS)) {
esSearch.addAggregation(stickyFacetBuilder.buildStickyFacet(IssueIndexDefinition.FIELD_ISSUE_TAGS, IssueFilterParameters.TAGS, query.tags().toArray()));
}
-
+ if (options.getFacets().contains(IssueFilterParameters.TYPES)) {
+ esSearch.addAggregation(stickyFacetBuilder.buildStickyFacet(IssueIndexDefinition.FIELD_ISSUE_TYPE, IssueFilterParameters.TYPES, query.types().toArray()));
+ }
if (options.getFacets().contains(IssueFilterParameters.RESOLUTIONS)) {
esSearch.addAggregation(createResolutionFacet(query, filters, esQuery));
}
public static final String FIELD_ISSUE_STATUS = "status";
public static final String FIELD_ISSUE_CHECKSUM = "checksum";
public static final String FIELD_ISSUE_TAGS = "tags";
+ public static final String FIELD_ISSUE_TYPE = "type";
/**
* Technical date
*/
issueMapping.stringFieldBuilder(FIELD_ISSUE_STATUS).enableSorting().build();
issueMapping.stringFieldBuilder(FIELD_ISSUE_TAGS).build();
issueMapping.createDateTimeField(FIELD_ISSUE_TECHNICAL_UPDATED_AT);
+ issueMapping.stringFieldBuilder(FIELD_ISSUE_TYPE).build();
}
}
import org.apache.commons.lang.StringUtils;
import org.sonar.api.resources.Scopes;
import org.sonar.api.rule.RuleKey;
+import org.sonar.core.issue.IssueType;
import org.sonar.db.DatabaseUtils;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
"p.module_uuid_path",
"p.path",
"p.scope",
- "i.tags"
+ "i.tags",
+ "i.issue_type"
};
private static final String SQL_ALL = "select " + StringUtils.join(FIELDS, ",") + " from issues i " +
doc.setDirectoryPath(extractDirPath(doc.filePath(), scope));
String tags = rs.getString(28);
doc.setTags(ImmutableList.copyOf(TAGS_SPLITTER.split(tags == null ? "" : tags)));
+ doc.setType(IssueType.valueOf(rs.getInt(29)));
return doc;
}
}
*/
package org.sonar.server.issue.ws;
+import org.sonar.api.issue.Issue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
-import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.issue.IssueService;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
String componentKey = request.mandatoryParam("component");
RuleKey ruleKey = RuleKey.parse(request.mandatoryParam("rule"));
- DefaultIssue issue = issueService.createManualIssue(componentKey, ruleKey,
+ Issue issue = issueService.createManualIssue(componentKey, ruleKey,
request.paramAsInt("line"),
request.param("message"),
request.param("severity"));
package org.sonar.server.issue.ws;
import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import com.google.common.io.Resources;
import java.util.Collection;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.server.ws.WebService.Param;
import org.sonar.api.utils.Paging;
+import org.sonar.core.issue.IssueType;
import org.sonar.server.rule.RuleKeyFunctions;
import org.sonar.server.es.Facets;
import org.sonar.server.es.SearchOptions;
import static com.google.common.collect.FluentIterable.from;
import static com.google.common.collect.Iterables.concat;
+import static java.lang.String.format;
import static java.util.Collections.singletonList;
import static org.sonar.api.utils.Paging.forPageIndex;
import static org.sonar.server.es.SearchOptions.MAX_LIMIT;
import static org.sonarqube.ws.client.issue.IssueFilterParameters.SEVERITIES;
import static org.sonarqube.ws.client.issue.IssueFilterParameters.STATUSES;
import static org.sonarqube.ws.client.issue.IssueFilterParameters.TAGS;
+import static org.sonarqube.ws.client.issue.IssueFilterParameters.TYPES;
public class SearchAction implements IssuesWsAction {
action.createParam(IssueFilterParameters.TAGS)
.setDescription("Comma-separated list of tags.")
.setExampleValue("security,convention");
+ action.createParam(IssueFilterParameters.TYPES)
+ .setDescription("Comma-separated list of types.")
+ .setSince("5.5")
+ .setPossibleValues(IssueType.values())
+ .setExampleValue(format("%s,%s", IssueType.CODE_SMELL, IssueType.BUG));
action.createParam(ACTION_PLANS)
.setDescription("Comma-separated list of action plan keys (not names)")
.setExampleValue("3f19de90-1521-4482-a737-a311758ff513");
addMandatoryValuesToFacet(facets, IssueFilterParameters.RULES, request.getRules());
addMandatoryValuesToFacet(facets, IssueFilterParameters.LANGUAGES, request.getLanguages());
addMandatoryValuesToFacet(facets, IssueFilterParameters.TAGS, request.getTags());
+ addMandatoryValuesToFacet(facets, IssueFilterParameters.TYPES, request.getTypes());
List<String> actionPlans = Lists.newArrayList("");
List<String> actionPlansFromRequest = request.getActionPlans();
if (actionPlansFromRequest != null) {
.setSort(request.param(Param.SORT))
.setSeverities(request.paramAsStrings(SEVERITIES))
.setStatuses(request.paramAsStrings(STATUSES))
- .setTags(request.paramAsStrings(TAGS));
+ .setTags(request.paramAsStrings(TAGS))
+ .setTypes(request.paramAsStrings(TYPES));
}
private enum IssueDocToKey implements Function<IssueDoc, String> {
private void formatIssue(Issues.Issue.Builder issueBuilder, IssueDto dto, SearchResponseData data) {
issueBuilder.setKey(dto.getKey());
+ Issues.IssueType type = Issues.IssueType.valueOf(dto.getType());
+ if (type != null) {
+ issueBuilder.setType(type);
+ }
ComponentDto component = data.getComponentByUuid(dto.getComponentUuid());
issueBuilder.setComponent(dto.getComponentKey());
// Only used for the compatibility with the Java WS Client <= 4.4 used by Eclipse
"creationDate": "2013-05-13T17:55:39+0200",
"updateDate": "2013-05-13T17:55:39+0200",
"tags": ["bug"],
+ "type": "RELIABILITY",
"comments": [
{
"key": "7d7c56f5-7b5a-41b9-87f8-36fa70caa5ba",
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.server.debt.DebtRemediationFunction;
+import org.sonar.core.issue.IssueType;
import static java.util.Objects.requireNonNull;
private RuleKey key;
private String name;
private RuleStatus status = RuleStatus.READY;
+ private IssueType type = IssueType.CODE_SMELL;
private Set<String> tags = new HashSet<>();
private DebtRemediationFunction function;
return requireNonNull(tags);
}
+ @Override
+ public IssueType getType() {
+ return type;
+ }
+
@Override
public DebtRemediationFunction getRemediationFunction() {
return function;
public void setTags(Set<String> tags) {
this.tags = tags;
}
+
+ public void setType(IssueType type) {
+ this.type = type;
+ }
}
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueType;
import org.sonar.server.issue.IssueUpdater;
import org.sonar.server.computation.analysis.AnalysisMetadataHolderRule;
import org.sonar.server.computation.component.Component;
@Test
public void display_warning_when_line_is_above_max_size() throws Exception {
setSingleChangeset("john", 123456789L, "rev-1");
- DefaultIssue issue = new DefaultIssue().setLine(2);
+ DefaultIssue issue = new DefaultIssue().setLine(2).setType(IssueType.VULNERABILITY);
underTest.onIssue(FILE, issue);
assertThat(logTester.logs(LoggerLevel.WARN)).containsOnly(
- "No SCM info has been found for issue DefaultIssue[key=<null>,componentUuid=<null>,componentKey=<null>,moduleUuid=<null>,moduleUuidPath=<null>," +
- "projectUuid=<null>,projectKey=<null>,ruleKey=<null>,language=<null>,severity=<null>,manualSeverity=false,message=<null>,line=2,effortToFix=<null>,debt=<null>," +
- "status=<null>,resolution=<null>,reporter=<null>,assignee=<null>,checksum=<null>,attributes=<null>,authorLogin=<null>,actionPlanKey=<null>,comments=<null>,tags=<null>,l" +
- "ocations=<null>,creationDate=<null>,updateDate=<null>,closeDate=<null>,currentChange=<null>,changes=<null>,isNew=true,beingClosed=false,onDisabledRule=false," +
- "isChanged=false,sendNotifications=false,selectedAt=<null>]");
+ "No SCM info has been found for issue DefaultIssue[key=<null>,type=VULNERABILITY,componentUuid=<null>,componentKey=<null>,moduleUuid=<null>,moduleUuidPath=<null>,projectUuid=<null>,projectKey=<null>,ruleKey=<null>,language=<null>,severity=<null>,manualSeverity=false,message=<null>,line=2,effortToFix=<null>,debt=<null>,status=<null>,resolution=<null>,reporter=<null>,assignee=<null>,checksum=<null>,attributes=<null>,authorLogin=<null>,actionPlanKey=<null>,comments=<null>,tags=<null>,locations=<null>,creationDate=<null>,updateDate=<null>,closeDate=<null>,currentChange=<null>,changes=<null>,isNew=true,beingClosed=false,onDisabledRule=false,isChanged=false,sendNotifications=false,selectedAt=<null>]");
}
private void setSingleChangeset(String author, Long date, String revision) {
RuleTagsCopier underTest = new RuleTagsCopier(ruleRepository);
@Test
- public void copy_tags_if_new_rule() {
+ public void copy_tags_if_new_issue() {
rule.setTags(Sets.newHashSet("bug", "performance"));
issue.setNew(true);
}
@Test
- public void do_not_copy_tags_if_existing_rule() {
+ public void do_not_copy_tags_if_existing_issue() {
rule.setTags(Sets.newHashSet("bug", "performance"));
issue.setNew(false).setTags(asList("misra"));
}
@Test
- public void do_not_copy_tags_if_existing_rule_without_tags() {
+ public void do_not_copy_tags_if_existing_issue_without_tags() {
rule.setTags(Sets.newHashSet("bug", "performance"));
issue.setNew(false).setTags(Collections.<String>emptyList());
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.server.computation.issue;
+
+import org.junit.Test;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueType;
+import org.sonar.server.computation.component.Component;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.sonar.db.rule.RuleTesting.XOO_X1;
+
+public class RuleTypeCopierTest {
+
+ DumbRule rule = new DumbRule(XOO_X1);
+
+ @org.junit.Rule
+ public RuleRepositoryRule ruleRepository = new RuleRepositoryRule().add(rule);
+
+ DefaultIssue issue = new DefaultIssue().setRuleKey(rule.getKey());
+ RuleTypeCopier underTest = new RuleTypeCopier(ruleRepository);
+
+ @Test
+ public void copy_rule_type_if_missing() {
+ rule.setType(IssueType.BUG);
+
+ underTest.onIssue(mock(Component.class), issue);
+
+ assertThat(issue.type()).isEqualTo(IssueType.BUG);
+ }
+
+ @Test
+ public void do_not_copy_type_if_present() {
+ rule.setType(IssueType.BUG);
+ issue.setType(IssueType.VULNERABILITY);
+
+ underTest.onIssue(mock(Component.class), issue);
+
+ assertThat(issue.type()).isEqualTo(IssueType.VULNERABILITY);
+ }
+}
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.DateUtils;
import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueType;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.issue.IssueMapper;
public void should_reload_issue_and_resolve_conflict() {
DefaultIssue issue = new DefaultIssue()
.setKey("ABCDE")
+ .setType(IssueType.CODE_SMELL)
.setRuleKey(RuleKey.of("squid", "AvoidCycles"))
.setComponentKey("struts:org.apache.struts.Action")
.setNew(false)
when(mapper.selectByKey("ABCDE")).thenReturn(
new IssueDto()
.setKee("ABCDE")
+ .setType(IssueType.CODE_SMELL)
.setRuleId(10)
.setRuleKey("squid", "AvoidCycles")
.setComponentKey("struts:org.apache.struts.Action")
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.DefaultIssueComment;
import org.sonar.core.issue.FieldDiffs;
+import org.sonar.core.issue.IssueType;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
issueCache.newAppender().append(new DefaultIssue()
.setKey("ISSUE")
+ .setType(IssueType.CODE_SMELL)
.setRuleKey(RuleKey.of("xoo", "S01"))
.setComponentUuid("COMPONENT")
.setProjectUuid("PROJECT")
issueCache.newAppender().append(new DefaultIssue()
.setKey("ISSUE")
+ .setType(IssueType.CODE_SMELL)
.setRuleKey(RuleKey.of("xoo", "S01"))
.setComponentUuid("COMPONENT")
.setProjectUuid("PROJECT")
issueCache.newAppender().append(new DefaultIssue()
.setKey("ISSUE")
+ .setType(IssueType.CODE_SMELL)
.setRuleKey(RuleKey.of("xoo", "S01"))
.setComponentUuid("COMPONENT")
.setProjectUuid("PROJECT")
issueCache.newAppender().append(new DefaultIssue()
.setKey("ISSUE")
+ .setType(IssueType.CODE_SMELL)
.setRuleKey(RuleKey.of("xoo", "S01"))
.setComponentUuid("COMPONENT")
.setProjectUuid("PROJECT")
.assignees(newArrayList("gargantua"))
.languages(newArrayList("xoo"))
.tags(newArrayList("tag1", "tag2"))
+ .types(newArrayList("RELIABILITY", "SECURITY"))
.assigned(true)
.hideRules(true)
.createdAfter(new Date())
assertThat(query.assignees()).containsOnly("gargantua");
assertThat(query.languages()).containsOnly("xoo");
assertThat(query.tags()).containsOnly("tag1", "tag2");
+ assertThat(query.types()).containsOnly("RELIABILITY", "SECURITY");
assertThat(query.assigned()).isTrue();
assertThat(query.hideRules()).isTrue();
assertThat(query.rules()).containsOnly(RuleKey.of("squid", "AvoidCycle"));
.severities(null)
.languages(null)
.tags(null)
+ .types(null)
.build();
assertThat(query.issueKeys()).isEmpty();
assertThat(query.componentUuids()).isEmpty();
assertThat(query.severities()).isEmpty();
assertThat(query.languages()).isEmpty();
assertThat(query.tags()).isEmpty();
+ assertThat(query.types()).isEmpty();
}
@Test
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.DefaultIssueComment;
import org.sonar.core.issue.IssueChangeContext;
+import org.sonar.core.issue.IssueType;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
Date date = DateUtils.parseDateTime("2013-05-18T12:00:00+0000");
DefaultIssue issue = new DefaultIssue()
.setKey("ABCDE")
+ .setType(IssueType.BUG)
.setNew(true)
.setRuleKey(RuleKey.of("squid", "AvoidCycle"))
Date date = DateUtils.parseDateTime("2013-05-18T12:00:00+0000");
DefaultIssue issue = new DefaultIssue()
.setKey("ABCDE")
+ .setType(IssueType.BUG)
.setNew(true)
.setRuleKey(RuleKey.of("squid", "AvoidCycle"))
Date date = DateUtils.parseDateTime("2013-05-18T12:00:00+0000");
DefaultIssue issue = new DefaultIssue()
.setKey("ABCDE")
+ .setType(IssueType.BUG)
.setNew(true)
.setRuleKey(RuleKey.of("squid", "AvoidCycle"))
Date date = DateUtils.parseDateTime("2013-05-18T12:00:00+0000");
DefaultIssue issue = new DefaultIssue()
.setKey("ABCDE")
+ .setType(IssueType.BUG)
.setNew(false)
.setChanged(true)
Date date = DateUtils.parseDateTime("2013-05-18T12:00:00+0000");
DefaultIssue issue = new DefaultIssue()
.setKey("ABCDE")
+ .setType(IssueType.BUG)
.setNew(false)
.setChanged(true)
import org.sonar.api.resources.Scopes;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.DateUtils;
+import org.sonar.core.issue.IssueType;
import org.sonar.core.util.Uuids;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.issue.IssueDto;
return new IssueDto()
.setKee(Uuids.create())
.setRule(rule)
+ .setType(IssueType.CODE_SMELL)
.setComponent(file)
.setProject(project)
.setStatus(Issue.STATUS_OPEN)
IssueDoc doc = new IssueDoc(Maps.<String, Object>newHashMap());
doc.setKey("ABC");
doc.setRuleKey(RuleTesting.XOO_X1.toString());
+ doc.setType(IssueType.CODE_SMELL);
doc.setActionPlanKey(null);
doc.setReporter(null);
doc.setAssignee("steve");
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.DefaultIssueComment;
import org.sonar.core.issue.IssueChangeContext;
+import org.sonar.core.issue.IssueType;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.server.issue.index.IssueIndexer;
Date date = DateUtils.parseDateTime("2013-05-18T12:00:00+0000");
DefaultIssue issue = new DefaultIssue()
.setKey("ABCDE")
+ .setType(IssueType.BUG)
.setNew(true)
.setRuleKey(RuleKey.of("squid", "AvoidCycle"))
Date date = DateUtils.parseDateTime("2013-05-18T12:00:00+0000");
DefaultIssue issue = new DefaultIssue()
.setKey("ABCDE")
+ .setType(IssueType.BUG)
.setNew(false)
.setChanged(true)
import org.sonar.core.issue.DefaultActionPlan;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.IssueChangeContext;
+import org.sonar.core.issue.IssueType;
+import org.sonar.server.issue.IssueTesting;
import org.sonar.server.issue.IssueUpdater;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
when(actionPlanDao.selectByKey("ABCD")).thenReturn(new ActionPlanDto().setKey("ABCD").setProjectKey_unit_test_only(PROJECT_KEY));
when(resourceDao.selectResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setKey(PROJECT_KEY).setId(1l));
- IssueDto issueDto = new IssueDto().setId(100L).setStatus(Issue.STATUS_OPEN).setRuleKey("squid", "s100").setIssueCreationDate(new Date());
+ IssueDto issueDto = new IssueDto().setId(100L).setStatus(Issue.STATUS_OPEN).setRuleKey("squid", "s100").setIssueCreationDate(new Date()).setType(IssueType.BUG);
when(issueDao.selectByActionPlan(session, "ABCD")).thenReturn(newArrayList(issueDto));
when(issueUpdater.plan(any(DefaultIssue.class), eq((ActionPlan) null), any(IssueChangeContext.class))).thenReturn(true);
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.test.DbTests;
+import org.sonarqube.ws.Issues;
import static org.assertj.core.api.Assertions.assertThat;
assertThat(issue.effortToFix()).isEqualTo(2d);
assertThat(issue.actionPlanKey()).isEqualTo("PLAN1");
assertThat(issue.attribute("JIRA")).isEqualTo("http://jira.com");
+ assertThat(issue.type().getDbConstant()).isEqualTo(2);
}
@Test
assertThat(issue.filePath()).isEqualTo("src/main/java/Action.java");
assertThat(issue.tags()).containsOnly("tag1", "tag2", "tag3");
assertThat(issue.debt().toMinutes()).isGreaterThan(0L);
+ assertThat(issue.type().getDbConstant()).isEqualTo(1);
issue = issuesByKey.get("BCD");
assertThat(issue.key()).isEqualTo("BCD");
assertThat(issue.filePath()).isNull();
assertThat(issue.tags()).containsOnly("tag1", "tag2", "tag3");
assertThat(issue.debt().toMinutes()).isGreaterThan(0L);
+ assertThat(issue.type().getDbConstant()).isEqualTo(2);
issue = issuesByKey.get("DEF");
assertThat(issue.key()).isEqualTo("DEF");
assertThat(issue.filePath()).isEqualTo("src/main/java/Action.java");
assertThat(issue.tags()).isEmpty();
assertThat(issue.debt().toMinutes()).isGreaterThan(0L);
+ assertThat(issue.type().getDbConstant()).isEqualTo(1);
issue = issuesByKey.get("EFG");
assertThat(issue.key()).isEqualTo("EFG");
assertThat(issue.filePath()).isEqualTo("src/main/java");
assertThat(issue.tags()).isEmpty();
assertThat(issue.debt().toMinutes()).isGreaterThan(0L);
+ assertThat(issue.type().getDbConstant()).isEqualTo(1);
}
@Test
assertThat(show.isPost()).isFalse();
assertThat(show.isInternal()).isFalse();
assertThat(show.responseExampleAsString()).isNotEmpty();
- assertThat(show.params()).hasSize(37);
+ assertThat(show.params()).hasSize(38);
}
@Test
created_at="1300000000000"
updated_at="1400000000000"
locations="[null]"
+ issue_type="1"
/>
</dataset>
created_at="1400000000000"
updated_at="1400000000000"
locations="[null]"
+ issue_type="1"
/>
</dataset>
created_at="1300000000000"
updated_at="1300000000000"
locations="[null]"
+ issue_type="[null]"
/>
</dataset>
issue_update_date="1368878400000"
issue_close_date="1368878400000"
locations="[null]"
+ issue_type="2"
/>
<issue_changes id="1" kee="FGHIJ" issue_key="ABCDE" change_type="comment" user_login="emmerik"
issue_update_date="1368828000000"
issue_close_date="[null]"
locations="[null]"
+ issue_type="2"
/>
</dataset>
issue_update_date="1368878400000"
issue_close_date="[null]"
locations="[null]"
+ issue_type="2"
/>
</dataset>
issue_update_date="1368878400000"
issue_close_date="1368878400000"
locations="[null]"
+ issue_type="2"
/>
<issue_changes id="1" kee="FGHIJ" issue_key="ABCDE" change_type="comment" user_login="emmerik"
issue_update_date="1265065200000"
issue_close_date="[null]"
locations="[null]"
+ issue_type="2"
/>
</dataset>
issue_update_date="1368878400000"
issue_close_date="1368878400000"
locations="[null]"
+ issue_type="2"
/>
<issue_changes id="1" kee="FGHIJ" issue_key="ABCDE" change_type="comment" user_login="emmerik"
issue_update_date="1368878400000"
issue_close_date="1368878400000"
locations="[null]"
+ issue_type="2"
/>
<issue_changes id="1" kee="FGHIJ" issue_key="ABCDE" change_type="comment" user_login="emmerik"
issue_update_date="1265065200000"
issue_close_date="[null]"
locations="[null]"
+ issue_type="[null]"
/>
</dataset>
issue_update_date="1368828000000"
issue_close_date="[null]"
locations="[null]"
+ issue_type="2"
/>
</dataset>
issue_update_date="1368828000000"
issue_close_date="[null]"
locations="[null]"
+ issue_type="2"
/>
<!-- Project 2 -->
issue_update_date="1368828000000"
issue_close_date="[null]"
locations="[null]"
+ issue_type="2"
/>
</dataset>
issue_creation_date="1115848800000"
issue_update_date="1356994800000"
issue_close_date="[null]"
- locations="[null]"/>
+ locations="[null]"
+ issue_type="1"/>
<issues
id="2"
issue_creation_date="1115848800000"
issue_update_date="1368828000000"
issue_close_date="[null]"
- locations="[null]"/>
+ locations="[null]"
+ issue_type="1"/>
<issues
id="3"
issue_creation_date="1115848800000"
issue_update_date="1368828000000"
issue_close_date="[null]"
- locations="[null]"/>
+ locations="[null]"
+ issue_type="1"/>
<issues
id="4"
issue_creation_date="1115848800000"
issue_update_date="1368828000000"
issue_close_date="[null]"
- locations="[null]"/>
+ locations="[null]"
+ issue_type="1"/>
</dataset>
issue_creation_date="1115848800000"
issue_update_date="1356994800000"
issue_close_date="[null]"
- locations="[null]"/>
+ locations="[null]"
+ issue_type="1"/>
<issues
id="2"
issue_creation_date="1115848800000"
issue_update_date="1368828000000"
issue_close_date="[null]"
- locations="[null]"/>
+ locations="[null]"
+ issue_type="1"/>
<issues
id="3"
issue_creation_date="1115848800000"
issue_update_date="1368828000000"
issue_close_date="[null]"
- locations="[null]"/>
+ locations="[null]"
+ issue_type="1"/>
<issues
id="4"
issue_creation_date="1115848800000"
issue_update_date="1368828000000"
issue_close_date="[null]"
- locations="[null]"/>
+ locations="[null]"
+ issue_type="1"/>
</dataset>
issue_update_date="1368828000000"
issue_close_date="[null]"
locations="[null]"
+ issue_type="1"
/>
<issues id="2"
issue_update_date="2368828000000"
issue_close_date="[null]"
locations="[null]"
+ issue_type="1"
/>
<!-- Project 2 -->
issue_update_date="1368828000000"
issue_close_date="[null]"
locations="[null]"
+ issue_type="1"
/>
</dataset>
issue_creation_date="1115848800000"
issue_update_date="1356994800000"
issue_close_date="[null]"
- locations="[null]"/>
+ locations="[null]"
+ issue_type="2"
+ />
</dataset>
issue_update_date="1356994800000"
issue_close_date="[null]"
locations="[null]"
+ issue_type="1"
/>
<issues
issue_update_date="1356994800000"
issue_close_date="[null]"
locations="[null]"
+ issue_type="2"
/>
<issues
issue_creation_date="1115848800000"
issue_update_date="1368828000000"
issue_close_date="[null]"
- locations="[null]"/>
+ locations="[null]"
+ issue_type="1"
+ />
<issues
id="4"
issue_update_date="1356994800000"
issue_close_date="[null]"
locations="[null]"
+ issue_type="1"
/>
</dataset>
--- /dev/null
+#
+# SonarQube, open source software quality management tool.
+# Copyright (C) 2008-2014 SonarSource
+# mailto:contact AT sonarsource DOT com
+#
+# SonarQube is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# SonarQube is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+#
+# SonarQube 5.5
+# SONAR-7333
+#
+class AddIssuesType < ActiveRecord::Migration
+
+ def self.up
+ execute_java_migration('org.sonar.db.version.v55.AddIssuesType')
+ end
+
+end
public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.Issue {
private String key;
-
+ private IssueType type;
private String componentUuid;
private String componentKey;
return this;
}
+ public IssueType type() {
+ return type;
+ }
+
+ public DefaultIssue setType(IssueType type) {
+ this.type = type;
+ return this;
+ }
+
/**
* Can be null on Views or Devs
*/
*/
package org.sonar.core.issue;
+import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import java.util.Map;
private Double effortToFix;
private String reporter;
private String assignee;
+ private IssueType type;
private Map<String, String> attributes;
public DefaultIssueBuilder() {
return this;
}
+ public DefaultIssueBuilder type(@Nullable IssueType type) {
+ this.type = type;
+ return this;
+ }
+
@Override
public DefaultIssueBuilder attribute(String key, @Nullable String value) {
if (attributes == null) {
DefaultIssue issue = new DefaultIssue();
String key = Uuids.create();
issue.setKey(key);
+ issue.setType(Objects.firstNonNull(type, IssueType.CODE_SMELL));
issue.setComponentKey(componentKey);
issue.setProjectKey(projectKey);
issue.setRuleKey(ruleKey);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.core.issue;
+
+import static java.lang.String.format;
+
+public enum IssueType {
+ CODE_SMELL(1), BUG(2), VULNERABILITY(3);
+
+ private final int dbConstant;
+
+ IssueType(int dbConstant) {
+ this.dbConstant = dbConstant;
+ }
+
+ public int getDbConstant() {
+ return dbConstant;
+ }
+
+ /**
+ * Returns the enum constant of the specified DB column value.
+ */
+ public static IssueType valueOf(int dbConstant) {
+ // iterating the array is fast-enough as size is small. No need for a map.
+ for (IssueType type : values()) {
+ if (type.getDbConstant() == dbConstant) {
+ return type;
+ }
+ }
+ throw new IllegalArgumentException(format("Unsupported value for db column ISSUES.ISSUE_TYPE: %d", dbConstant));
+ }
+}
import org.sonar.api.utils.Duration;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueType;
import org.sonar.core.util.Uuids;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.protobuf.DbIssues;
private static final Splitter TAGS_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
private Long id;
+ private int type;
private String kee;
private String componentUuid;
private String projectUuid;
public static IssueDto toDtoForComputationInsert(DefaultIssue issue, int ruleId, long now) {
return new IssueDto()
.setKee(issue.key())
+ .setType(issue.type())
.setLine(issue.line())
.setLocations((DbIssues.Locations) issue.getLocations())
.setMessage(issue.message())
// Invariant fields, like key and rule, can't be updated
return new IssueDto()
.setKee(issue.key())
+ .setType(issue.type())
.setLine(issue.line())
.setLocations((DbIssues.Locations) issue.getLocations())
.setMessage(issue.message())
return this;
}
+ public int getType() {
+ return type;
+ }
+
+ public IssueDto setType(int type) {
+ this.type = type;
+ return this;
+ }
+
+ public IssueDto setType(IssueType type) {
+ this.type = type.getDbConstant();
+ return this;
+ }
+
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
public DefaultIssue toDefaultIssue() {
DefaultIssue issue = new DefaultIssue();
issue.setKey(kee);
+ issue.setType(IssueType.valueOf(type));
issue.setStatus(status);
issue.setResolution(resolution);
issue.setMessage(message);
public class DatabaseVersion {
- public static final int LAST_VERSION = 1103;
+ public static final int LAST_VERSION = 1106;
/**
* The minimum supported version which can be upgraded. Lower
import org.sonar.db.version.v54.MigrateUsersIdentity;
import org.sonar.db.version.v54.RemoveComponentPageProperties;
import org.sonar.db.version.v54.RemovePreviewPermission;
+import org.sonar.db.version.v55.AddIssuesType;
import org.sonar.db.version.v55.AddRulesLongDateColumns;
import org.sonar.db.version.v55.DeleteMeasuresWithCharacteristicId;
import org.sonar.db.version.v55.FeedRulesLongDateColumns;
// 5.5
AddRulesLongDateColumns.class,
FeedRulesLongDateColumns.class,
- DeleteMeasuresWithCharacteristicId.class
- );
+ DeleteMeasuresWithCharacteristicId.class,
+ AddIssuesType.class
+ );
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.version;
+
+import javax.annotation.CheckForNull;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.sonar.db.version.ColumnDefValidation.validateColumnName;
+
+/**
+ * Integer that supports at least range [0..128]. Full range depends on database vendor.
+ */
+public class TinyIntColumnDef extends AbstractColumnDef {
+
+ private TinyIntColumnDef(Builder builder) {
+ super(builder.columnName, builder.isNullable);
+ }
+
+ @Override
+ public String generateSqlType(Dialect dialect) {
+ switch (dialect.getId()) {
+ case PostgreSql.ID:
+ return "SMALLINT";
+ case Oracle.ID:
+ return "NUMBER(3)";
+ case MySql.ID:
+ return "TINYINT(1)";
+ case MsSql.ID:
+ case H2.ID:
+ return "TINYINT";
+ default:
+ throw new UnsupportedOperationException(String.format("Unknown dialect '%s'", dialect.getId()));
+ }
+ }
+
+ public static class Builder {
+ @CheckForNull
+ private String columnName;
+ private boolean isNullable = true;
+
+ public Builder setColumnName(String columnName) {
+ this.columnName = validateColumnName(columnName);
+ return this;
+ }
+
+ public Builder setIsNullable(boolean isNullable) {
+ this.isNullable = isNullable;
+ return this;
+ }
+
+ public TinyIntColumnDef build() {
+ validateColumnName(columnName);
+ return new TinyIntColumnDef(this);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.version.v55;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.db.version.DdlChange;
+import org.sonar.db.version.TinyIntColumnDef;
+
+public class AddIssuesType extends DdlChange {
+
+ private final Database db;
+
+ public AddIssuesType(Database db) {
+ super(db);
+ this.db = db;
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(generateSql());
+ }
+
+ private String generateSql() {
+ return new AddColumnsBuilder(db.getDialect(), "issues")
+ .addColumn(new TinyIntColumnDef.Builder().setColumnName("issue_type").setIsNullable(true).build())
+ .build();
+ }
+
+}
p.module_uuid_path as moduleUuidPath,
p.path as filePath,
root.kee as projectKey,
- i.project_uuid as projectUuid
+ i.project_uuid as projectUuid,
+ i.issue_type as type
</sql>
<sql id="sortColumn">
INSERT INTO issues (kee, rule_id, action_plan_key, severity, manual_severity,
message, line, locations, effort_to_fix, technical_debt, status, tags,
resolution, checksum, reporter, assignee, author_login, issue_attributes, issue_creation_date, issue_update_date,
- issue_close_date, created_at, updated_at, component_uuid, project_uuid)
+ issue_close_date, created_at, updated_at, component_uuid, project_uuid, issue_type)
VALUES (#{kee,jdbcType=VARCHAR}, #{ruleId,jdbcType=INTEGER}, #{actionPlanKey,jdbcType=VARCHAR},
#{severity,jdbcType=VARCHAR},
#{manualSeverity,jdbcType=BOOLEAN}, #{message,jdbcType=VARCHAR}, #{line,jdbcType=INTEGER},
#{issueAttributes,jdbcType=VARCHAR},
#{issueCreationTime,jdbcType=BIGINT},#{issueUpdateTime,jdbcType=BIGINT}, #{issueCloseTime,jdbcType=BIGINT},
#{createdAt,jdbcType=BIGINT}, #{updatedAt,jdbcType=BIGINT},
- #{componentUuid,jdbcType=VARCHAR}, #{projectUuid,jdbcType=VARCHAR})
+ #{componentUuid,jdbcType=VARCHAR}, #{projectUuid,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER})
</insert>
<!--
issue_creation_date=#{issueCreationTime,jdbcType=BIGINT},
issue_update_date=#{issueUpdateTime,jdbcType=BIGINT},
issue_close_date=#{issueCloseTime,jdbcType=BIGINT},
- updated_at=#{updatedAt,jdbcType=BIGINT}
+ updated_at=#{updatedAt,jdbcType=BIGINT},
+ issue_type=#{type,jdbcType=INTEGER}
where kee = #{kee}
</update>
issue_creation_date=#{issueCreationTime,jdbcType=BIGINT},
issue_update_date=#{issueUpdateTime,jdbcType=BIGINT},
issue_close_date=#{issueCloseTime,jdbcType=BIGINT},
- updated_at=#{updatedAt,jdbcType=BIGINT}
+ updated_at=#{updatedAt,jdbcType=BIGINT},
+ issue_type=#{type,jdbcType=INTEGER}
where kee = #{kee} and updated_at <= #{selectedAt}
</update>
i.issue_close_date as issueCloseTime,
i.created_at as createdAt,
i.updated_at as updatedAt,
+ i.issue_type as type,
r.plugin_rule_key as ruleKey,
r.plugin_name as ruleRepo,
p.kee as componentKey,
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1101');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1102');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1103');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1106');
INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, EXTERNAL_IDENTITY, EXTERNAL_IDENTITY_PROVIDER, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'admin', 'sonarqube', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '1418215735482', '1418215735482', null, null);
ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
"CREATED_AT" BIGINT,
"UPDATED_AT" BIGINT,
"LOCATIONS" BLOB(167772150),
+ "ISSUE_TYPE" TINYINT
);
CREATE TABLE "ISSUE_CHANGES" (
import org.junit.rules.ExpectedException;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.System2;
+import org.sonar.core.issue.IssueType;
import org.sonar.db.DbTester;
import org.sonar.db.RowNotFoundException;
import org.sonar.db.component.ComponentDto;
dto.setProject(new ComponentDto().setKey("struts").setId(100L).setUuid("project-uuid"));
dto.setRule(RuleTesting.newDto(RuleKey.of("squid", "S001")).setId(200));
dto.setKee("ABCDE");
+ dto.setType(2);
dto.setLine(500);
dto.setEffortToFix(3.14);
dto.setDebt(10L);
import org.sonar.api.issue.Issue;
import org.sonar.api.utils.Duration;
import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueType;
import org.sonar.db.rule.RuleDto;
import static org.assertj.core.api.Assertions.assertThat;
IssueDto dto = new IssueDto()
.setKee("100")
+ .setType(IssueType.VULNERABILITY)
.setRuleId(1)
.setRuleKey("squid", "AvoidCycle")
.setLanguage("xoo")
DefaultIssue issue = dto.toDefaultIssue();
assertThat(issue.key()).isEqualTo("100");
+ assertThat(issue.type()).isEqualTo(IssueType.VULNERABILITY);
assertThat(issue.ruleKey().toString()).isEqualTo("squid:AvoidCycle");
assertThat(issue.language()).isEqualTo("xoo");
assertThat(issue.componentUuid()).isEqualTo("CDEF");
dto.setComponentUuid("uuid-123");
dto.setProjectUuid("uuid-100");
dto.setRuleId(200);
+ dto.setType(2);
dto.setKee("ABCDE");
dto.setLine(500);
dto.setEffortToFix(3.14);
dto.setComponentUuid("uuid-123");
dto.setProjectUuid("uuid-101");
dto.setRuleId(200);
+ dto.setType(3);
dto.setKee("ABCDE");
dto.setLine(500);
dto.setEffortToFix(3.14);
dto.setComponentUuid("uuid-123");
dto.setProjectUuid("uuid-101");
dto.setRuleId(200);
+ dto.setType(3);
dto.setKee("ABCDE");
dto.setLine(500);
dto.setEffortToFix(3.14);
public void verify_count_of_added_MigrationStep_types() {
ComponentContainer container = new ComponentContainer();
new MigrationStepModule().configure(container);
- assertThat(container.size()).isEqualTo(54);
+ assertThat(container.size()).isEqualTo(55);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.version;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+import org.sonar.db.dialect.PostgreSql;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class TinyIntColumnDefTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void build_string_column_def() throws Exception {
+ TinyIntColumnDef def = new TinyIntColumnDef.Builder()
+ .setColumnName("foo")
+ .setIsNullable(true)
+ .build();
+
+ assertThat(def.getName()).isEqualTo("foo");
+ assertThat(def.isNullable()).isTrue();
+ }
+
+ @Test
+ public void generate_sql_type() throws Exception {
+ TinyIntColumnDef def = new TinyIntColumnDef.Builder()
+ .setColumnName("foo")
+ .setIsNullable(true)
+ .build();
+
+ assertThat(def.generateSqlType(new H2())).isEqualTo("TINYINT");
+ assertThat(def.generateSqlType(new PostgreSql())).isEqualTo("SMALLINT");
+ assertThat(def.generateSqlType(new MsSql())).isEqualTo("TINYINT");
+ assertThat(def.generateSqlType(new MySql())).isEqualTo("TINYINT(1)");
+ assertThat(def.generateSqlType(new Oracle())).isEqualTo("NUMBER(3)");
+ }
+
+ @Test
+ public void fail_with_UOE_to_generate_sql_type_when_unknown_dialect() throws Exception {
+ thrown.expect(UnsupportedOperationException.class);
+ thrown.expectMessage("Unknown dialect 'unknown'");
+
+ TinyIntColumnDef def = new TinyIntColumnDef.Builder()
+ .setColumnName("foo")
+ .setIsNullable(true)
+ .build();
+
+ Dialect dialect = mock(Dialect.class);
+ when(dialect.getId()).thenReturn("unknown");
+ def.generateSqlType(dialect);
+ }
+}
updated_at="1450000000000"
action_plan_key="current_sprint"
locations="[null]"
+ issue_type="2"
/>
</dataset>
updated_at="1500000000000"
action_plan_key="current_sprint"
locations="[null]"
+ issue_type="2"
/>
</dataset>
updated_at="1500000000000"
action_plan_key="current_sprint"
locations="[null]"
+ issue_type="3"
/>
</dataset>
updated_at="1500000000000"
action_plan_key="[null]"
locations="[null]"
+ issue_type="2"
/>
</dataset>
updated_at="1450000000000"
action_plan_key="[null]"
locations="[null]"
+ issue_type="[null]"
/>
</dataset>
updated_at="1450000000000"
action_plan_key="[null]"
locations="[null]"
+ issue_type="[null]"
/>
</dataset>
updated_at="1450000000000" issue_creation_date="1366063200000" issue_update_date="1396994400000"
created_at="1450000000000" tags="[null]"
locations="[null]"
+ issue_type="[null]"
/>
<!-- Open issue on directory -->
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="1450000000000" issue_creation_date="1366063200000" issue_update_date="1396994400000"
- created_at="1450000000000" tags="[null]" locations="[null]"/>
+ created_at="1450000000000" tags="[null]" locations="[null]"
+ issue_type="[null]"/>
<!-- Open issue on project -->
<issues id="3" kee="ISSUE-3"
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="1450000000000" issue_creation_date="1366063200000" issue_update_date="1396994400000"
- created_at="1450000000000" tags="[null]" locations="[null]"/>
+ created_at="1450000000000" tags="[null]" locations="[null]"
+ issue_type="[null]"/>
<!-- Resolved issue on file -> not to be updated -->
<issues id="4" kee="ISSUE-4"
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="1450000000000" issue_creation_date="1366063200000" issue_update_date="1396908000000"
- created_at="1450000000000" tags="[null]" locations="[null]"/>
+ created_at="1450000000000" tags="[null]" locations="[null]"
+ issue_type="[null]"/>
</dataset>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1450000000000" locations="[null]"/>
+ created_at="1450000000000" locations="[null]"
+ issue_type="[null]"/>
<!-- Open issue on directory -->
<issues id="2" kee="ISSUE-2"
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1450000000000" locations="[null]"/>
+ created_at="1450000000000" locations="[null]"
+ issue_type="[null]"/>
<!-- Open issue on project -->
<issues id="3" kee="ISSUE-3"
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1450000000000" locations="[null]"/>
+ created_at="1450000000000" locations="[null]"
+ issue_type="[null]"/>
<!-- Resolved issue on file -> not to be updated -->
<issues id="4" kee="ISSUE-4"
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="1450000000000" issue_creation_date="1366063200000" issue_update_date="1396908000000"
- created_at="1450000000000" locations="[null]"/>
+ created_at="1450000000000" locations="[null]"
+ issue_type="[null]"/>
</dataset>
issue_update_date="1366063200000"
issue_close_date="1366063200000"
locations="[null]"
+ issue_type="[null]"
/>
<issues id="2" kee="ABCDF" component_uuid="A" project_uuid="A" status="CLOSED" resolution="[null]" line="200"
issue_update_date="1366063200000"
issue_close_date="1366063200000"
locations="[null]"
+ issue_type="[null]"
/>
<issue_changes id="1" kee="[null]" issue_key="ABCDF" created_at="[null]" updated_at="[null]" user_login="admin"
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="3" kee="[null]" issue_key="ISSUE-3" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="4" kee="[null]" issue_key="ISSUE-4" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="1" kee="[null]" issue_key="ISSUE-1" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="2" kee="[null]" issue_key="ISSUE-2" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="3" kee="[null]" issue_key="ISSUE-3" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="4" kee="[null]" issue_key="ISSUE-4" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="5" kee="[null]" issue_key="ISSUE-5" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="3" kee="[null]" issue_key="ISSUE-3" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="4" kee="[null]" issue_key="ISSUE-4" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="5" kee="[null]" issue_key="ISSUE-5" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="1" kee="[null]" issue_key="ISSUE-1" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="3" kee="[null]" issue_key="ISSUE-3" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="4" kee="[null]" issue_key="ISSUE-4" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]"
issue_attributes="[null]" checksum="[null]" author_login="[null]"
updated_at="[null]" issue_creation_date="1366063200000" issue_update_date="1366063200000"
- created_at="1400000000000" locations="[null]"/>
+ created_at="1400000000000" locations="[null]"
+ issue_type="[null]"/>
<issue_changes id="5" kee="[null]" issue_key="ISSUE-5" created_at="[null]" updated_at="[null]" user_login="admin"
change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
public static final String AUTHORS = "authors";
public static final String LANGUAGES = "languages";
public static final String TAGS = "tags";
+ public static final String TYPES = "types";
public static final String ASSIGNED = "assigned";
public static final String PLANNED = "planned";
public static final String HIDE_RULES = "hideRules";
public static final String FACET_ASSIGNED_TO_ME = "assigned_to_me";
- public static final List<String> ALL = ImmutableList.of(ISSUES, SEVERITIES, STATUSES, RESOLUTIONS, RESOLVED, COMPONENTS, COMPONENT_ROOTS, RULES, ACTION_PLANS, REPORTERS, TAGS,
+ public static final List<String> ALL = ImmutableList.of(ISSUES, SEVERITIES, STATUSES, RESOLUTIONS, RESOLVED, COMPONENTS, COMPONENT_ROOTS, RULES, ACTION_PLANS, REPORTERS, TAGS, TYPES,
ASSIGNEES, LANGUAGES, ASSIGNED, PLANNED, HIDE_RULES, CREATED_AT, CREATED_AFTER, CREATED_BEFORE, CREATED_IN_LAST, COMPONENT_UUIDS, COMPONENT_ROOT_UUIDS, FACET_MODE,
PROJECTS, PROJECT_UUIDS, PROJECT_KEYS, COMPONENT_KEYS, MODULE_UUIDS, DIRECTORIES, FILE_UUIDS, AUTHORS, HIDE_COMMENTS, PAGE_SIZE, PAGE_INDEX, SORT, ASC);
private List<String> severities;
private List<String> statuses;
private List<String> tags;
+ private List<String> types;
@CheckForNull
public List<String> getActionPlans() {
return this;
}
+ @CheckForNull
+ public List<String> getTypes() {
+ return types;
+ }
+
+ public SearchWsRequest setTypes(@Nullable List<String> types) {
+ this.types = types;
+ return this;
+ }
+
@CheckForNull
public List<String> getComponentRootUuids() {
return componentRootUuids;
repeated ActionPlan actionPlans = 5;
}
+enum IssueType {
+ // Zero is required in order to not get MAINTAINABILITY as default value
+ // See http://androiddevblog.com/protocol-buffers-pitfall-adding-enum-values/
+ UNKNOWN = 0;
+
+ // same name as in Java enum IssueType,
+ // same index values as in database (see column ISSUES.ISSUE_TYPE)
+ CODE_SMELL = 1;
+ BUG = 2;
+ VULNERABILITY = 3;
+}
message Issue {
optional string key = 1;
optional string updateDate = 24;
optional string fUpdateAge = 25;
optional string closeDate = 26;
+
+ optional IssueType type = 27;
}
message Transitions {