List<BatchReport.Issue> readComponentIssues(int componentRef);
- BatchReport.Issues readDeletedComponentIssues(int deletedComponentRef);
-
List<BatchReport.Duplication> readComponentDuplications(int componentRef);
List<BatchReport.Symbols.Symbol> readComponentSymbols(int componentRef);
return delegate.readComponentIssues(componentRef);
}
- @Override
- public BatchReport.Issues readDeletedComponentIssues(int deletedComponentRef) {
- return delegate.readDeletedComponentIssues(deletedComponentRef);
- }
-
@Override
public List<BatchReport.Duplication> readComponentDuplications(int componentRef) {
return delegate.readComponentDuplications(componentRef);
void visit(Component tree);
enum Order {
- PRE_ORDER, POST_ORDER
+ /**
+ * Each component is visited BEFORE its children. Top-down traversal of
+ * tree of components.
+ */
+ PRE_ORDER,
+
+ /**
+ * Each component is visited AFTER its children. Bottom-up traversal of
+ * tree of components.
+ */
+ POST_ORDER
}
}
/**
* Lazy loading of project settings.
*
- * Should be refactored to be able to load settings from any components.
+ * TODO Should be refactored to be able to load settings from any components.
*/
public class ProjectSettingsRepository {
import org.sonar.api.utils.log.Profiler;
import org.sonar.core.component.Module;
import org.sonar.core.issue.db.UpdateConflictResolver;
+import org.sonar.core.issue.tracking.Tracker;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.server.computation.ComputationService;
import org.sonar.server.computation.ReportQueue;
import org.sonar.server.computation.debt.DebtModelHolderImpl;
import org.sonar.server.computation.event.EventRepositoryImpl;
import org.sonar.server.computation.formula.CoreFormulaRepositoryImpl;
+import org.sonar.server.computation.issue.BaseIssuesLoader;
+import org.sonar.server.computation.issue.DebtCalculator;
+import org.sonar.server.computation.issue.DefaultAssignee;
+import org.sonar.server.computation.issue.IssueAssigner;
import org.sonar.server.computation.issue.IssueCache;
-import org.sonar.server.computation.issue.IssueComputation;
+import org.sonar.server.computation.issue.IssueLifecycle;
+import org.sonar.server.computation.issue.IssueListeners;
import org.sonar.server.computation.issue.RuleCache;
import org.sonar.server.computation.issue.RuleCacheLoader;
-import org.sonar.server.computation.issue.ScmAccountCache;
-import org.sonar.server.computation.issue.ScmAccountCacheLoader;
-import org.sonar.server.computation.issue.SourceLinesCache;
+import org.sonar.server.computation.issue.RuleTagsCopier;
+import org.sonar.server.computation.issue.ScmAccountToUser;
+import org.sonar.server.computation.issue.ScmAccountToUserLoader;
+import org.sonar.server.computation.issue.TrackerBaseInputFactory;
+import org.sonar.server.computation.issue.TrackerExecution;
+import org.sonar.server.computation.issue.TrackerRawInputFactory;
import org.sonar.server.computation.language.LanguageRepositoryImpl;
import org.sonar.server.computation.measure.MeasureRepositoryImpl;
import org.sonar.server.computation.measure.newcoverage.NewCoverageMetricKeysModule;
NewCoverageMetricKeysModule.class,
// issues
- ScmAccountCacheLoader.class,
- ScmAccountCache.class,
- SourceLinesCache.class,
- IssueComputation.class,
+ ScmAccountToUserLoader.class,
+ ScmAccountToUser.class,
+ IssueAssigner.class,
+ RuleTagsCopier.class,
RuleCache.class,
RuleCacheLoader.class,
IssueCache.class,
+ DefaultAssignee.class,
+ DebtCalculator.class,
+ IssueListeners.class,
+ IssueLifecycle.class,
UpdateConflictResolver.class,
+ TrackerBaseInputFactory.class,
+ TrackerRawInputFactory.class,
+ Tracker.class,
+ TrackerExecution.class,
+ BaseIssuesLoader.class,
// views
ViewIndex.class,
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import com.google.common.collect.ImmutableMap;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ibatis.session.ResultContext;
+import org.apache.ibatis.session.ResultHandler;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.db.IssueDto;
+import org.sonar.core.issue.db.IssueMapper;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.computation.component.TreeRootHolder;
+import org.sonar.server.db.DbClient;
+
+/**
+ * Loads all the project open issues from database, including manual issues.
+ */
+public class BaseIssuesLoader {
+
+ private final TreeRootHolder treeRootHolder;
+ private final DbClient dbClient;
+ private final RuleCache ruleCache;
+
+ public BaseIssuesLoader(TreeRootHolder treeRootHolder, DbClient dbClient, RuleCache ruleCache) {
+ this.treeRootHolder = treeRootHolder;
+ this.dbClient = dbClient;
+ this.ruleCache = ruleCache;
+ }
+
+ public List<DefaultIssue> loadForComponentUuid(String componentUuid) {
+ DbSession session = dbClient.openSession(false);
+ final List<DefaultIssue> result = new ArrayList<>();
+ try {
+ Map<String, String> params = ImmutableMap.of("componentUuid", componentUuid);
+ session.select(IssueMapper.class.getName() + ".selectOpenByComponentUuid", params, new ResultHandler() {
+ @Override
+ public void handleResult(ResultContext resultContext) {
+ DefaultIssue issue = ((IssueDto) resultContext.getResultObject()).toDefaultIssue();
+ issue.setOnDisabledRule(ruleCache.getNullable(issue.ruleKey()) == null);
+ result.add(issue);
+ }
+ });
+ return result;
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ /**
+ * Uuids of all the components that have open issues on this project.
+ */
+ public Set<String> loadComponentUuids() {
+ DbSession session = dbClient.openSession(false);
+ try {
+ return dbClient.issueDao().selectComponentUuidsOfOpenIssuesForProjectUuid(session, treeRootHolder.getRoot().getUuid());
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.server.computation.component.Component;
+
+public class DebtCalculator extends IssueListener {
+
+ @Override
+ public void beforeIssue(Component component, DefaultIssue issue) {
+ if (issue.resolution() == null) {
+ // TODO
+ }
+ }
+}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import com.google.common.base.Strings;
+import javax.annotation.CheckForNull;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.server.computation.component.ProjectSettingsRepository;
+import org.sonar.server.computation.component.TreeRootHolder;
+import org.sonar.server.user.index.UserDoc;
+import org.sonar.server.user.index.UserIndex;
+
+/**
+ * The user who is optionally declared as being the assignee
+ * of all the issues which SCM author is not associated with any SonarQube user.
+ */
+public class DefaultAssignee {
+
+ private static final Logger LOG = Loggers.get(DefaultAssignee.class);
+
+ private final TreeRootHolder treeRootHolder;
+ private final UserIndex userIndex;
+ private final ProjectSettingsRepository settings;
+
+ private boolean loaded = false;
+ private String login = null;
+
+ public DefaultAssignee(TreeRootHolder treeRootHolder, UserIndex userIndex, ProjectSettingsRepository settings) {
+ this.treeRootHolder = treeRootHolder;
+ this.userIndex = userIndex;
+ this.settings = settings;
+ }
+
+ @CheckForNull
+ public String getLogin() {
+ if (!loaded) {
+ String configuredLogin = settings.getProjectSettings(treeRootHolder.getRoot().getKey()).getString(CoreProperties.DEFAULT_ISSUE_ASSIGNEE);
+ if (!Strings.isNullOrEmpty(configuredLogin) && isValidLogin(configuredLogin)) {
+ this.login = configuredLogin;
+ }
+ loaded = true;
+ }
+ return login;
+ }
+
+ private boolean isValidLogin(String s) {
+ UserDoc user = userIndex.getNullableByLogin(s);
+ if (user == null) {
+ LOG.info("the {} property was set with an unknown login: {}", CoreProperties.DEFAULT_ISSUE_ASSIGNEE, s);
+ return false;
+ }
+ return true;
+ }
+}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import com.google.common.collect.Sets;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.tracking.Tracking;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
+import org.sonar.server.computation.component.TreeRootHolder;
+import org.sonar.server.computation.step.ComputationStep;
+import org.sonar.server.util.cache.DiskCache;
+
+import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.POST_ORDER;
+
+public class IntegrateIssuesStep implements ComputationStep {
+
+ private final TreeRootHolder treeRootHolder;
+ private final TrackerExecution tracker;
+ private final IssueCache issueCache;
+ private final BaseIssuesLoader baseIssuesLoader;
+ private final IssueLifecycle issueLifecycle;
+ private final IssueListeners issueListeners;
+
+ public IntegrateIssuesStep(TreeRootHolder treeRootHolder, TrackerExecution tracker, IssueCache issueCache,
+ BaseIssuesLoader baseIssuesLoader, IssueLifecycle issueLifecycle,
+ IssueListeners issueListeners) {
+ this.treeRootHolder = treeRootHolder;
+ this.tracker = tracker;
+ this.issueCache = issueCache;
+ this.baseIssuesLoader = baseIssuesLoader;
+ this.issueLifecycle = issueLifecycle;
+ this.issueListeners = issueListeners;
+ }
+
+ @Override
+ public void execute() {
+ // all the components that had issues before this analysis
+ final Set<String> unprocessedComponentUuids = Sets.newHashSet(baseIssuesLoader.loadComponentUuids());
+
+ new DepthTraversalTypeAwareVisitor(Component.Type.FILE, POST_ORDER) {
+ @Override
+ public void visitAny(Component component) {
+ processIssues(component);
+ unprocessedComponentUuids.remove(component.getUuid());
+ }
+ }.visit(treeRootHolder.getRoot());
+
+ closeIssuesForDeletedComponentUuids(unprocessedComponentUuids);
+ }
+
+ private void processIssues(Component component) {
+ Tracking<DefaultIssue, DefaultIssue> tracking = tracker.track(component);
+ DiskCache<DefaultIssue>.DiskAppender cacheAppender = issueCache.newAppender();
+ try {
+ issueListeners.beforeComponent(component, tracking);
+ fillNewOpenIssues(component, tracking, cacheAppender);
+ fillExistingOpenIssues(component, tracking, cacheAppender);
+ closeUnmatchedBaseIssues(component, tracking, cacheAppender);
+ issueListeners.afterComponent(component);
+ } finally {
+ cacheAppender.close();
+ }
+ }
+
+ private void fillNewOpenIssues(Component component, Tracking<DefaultIssue, DefaultIssue> tracking, DiskCache<DefaultIssue>.DiskAppender cacheAppender) {
+ Set<DefaultIssue> issues = tracking.getUnmatchedRaws();
+ for (DefaultIssue issue : issues) {
+ issueLifecycle.initNewOpenIssue(issue);
+ issueListeners.beforeIssue(component, issue);
+ process(component, issue, cacheAppender);
+ }
+ }
+
+ private void fillExistingOpenIssues(Component component, Tracking<DefaultIssue, DefaultIssue> tracking, DiskCache<DefaultIssue>.DiskAppender cacheAppender) {
+ for (Map.Entry<DefaultIssue, DefaultIssue> entry : tracking.getMatchedRaws().entrySet()) {
+ DefaultIssue raw = entry.getKey();
+ DefaultIssue base = entry.getValue();
+ issueListeners.beforeIssue(component, raw);
+ issueLifecycle.mergeExistingOpenIssue(raw, base);
+ process(component, raw, cacheAppender);
+ }
+ for (Map.Entry<Integer, DefaultIssue> entry : tracking.getOpenManualIssuesByLine().entries()) {
+ int line = entry.getKey();
+ DefaultIssue manualIssue = entry.getValue();
+ manualIssue.setLine(line == 0 ? null : line);
+ issueListeners.beforeIssue(component, manualIssue);
+ process(component, manualIssue, cacheAppender);
+ }
+ }
+
+ private void closeUnmatchedBaseIssues(Component component, Tracking<DefaultIssue, DefaultIssue> tracking, DiskCache<DefaultIssue>.DiskAppender cacheAppender) {
+ for (DefaultIssue issue : tracking.getUnmatchedBases()) {
+ // TODO should replace flag "beingClosed" by express call to transition "automaticClose"
+ issue.setBeingClosed(true);
+ // TODO manual issues -> was updater.setResolution(newIssue, Issue.RESOLUTION_REMOVED, changeContext);. Is it a problem ?
+ process(component, issue, cacheAppender);
+ }
+ }
+
+ private void process(Component component, DefaultIssue issue, DiskCache<DefaultIssue>.DiskAppender cacheAppender) {
+ issueLifecycle.doAutomaticTransition(issue);
+ issueListeners.onIssue(component, issue);
+ cacheAppender.append(issue);
+ }
+
+ private void closeIssuesForDeletedComponentUuids(Set<String> deletedComponentUuids) {
+ DiskCache<DefaultIssue>.DiskAppender cacheAppender = issueCache.newAppender();
+ try {
+ for (String deletedComponentUuid : deletedComponentUuids) {
+ List<DefaultIssue> issues = baseIssuesLoader.loadForComponentUuid(deletedComponentUuid);
+ for (DefaultIssue issue : issues) {
+ issue.setBeingClosed(true);
+ issueLifecycle.doAutomaticTransition(issue);
+ // TODO execute listeners ? Component is currently missing.
+ cacheAppender.append(issue);
+ }
+ }
+ } finally {
+ cacheAppender.close();
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "Integrate issues";
+ }
+
+}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.tracking.Tracking;
+import org.sonar.server.computation.batch.BatchReportReader;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.source.index.SourceLineDoc;
+import org.sonar.server.source.index.SourceLineIndex;
+
+/**
+ * Detect the SCM author and SQ assignee.
+ * <p/>
+ * It relies on:
+ * <ul>
+ * <li>the SCM information sent in the report for modified files</li>
+ * <li>the Elasticsearch index of source lines for non-modified files</li>
+ * </ul>
+ */
+public class IssueAssigner extends IssueListener {
+
+ private final SourceLineIndex sourceLineIndex;
+ private final BatchReportReader reportReader;
+ private final DefaultAssignee defaultAssigne;
+ private final ScmAccountToUser scmAccountToUser;
+
+ private long lastCommitDate = 0L;
+ private String lastCommitAuthor = null;
+ private BatchReport.Changesets scmChangesets = null;
+
+ public IssueAssigner(SourceLineIndex sourceLineIndex, BatchReportReader reportReader,
+ ScmAccountToUser scmAccountToUser, DefaultAssignee defaultAssigne) {
+ this.sourceLineIndex = sourceLineIndex;
+ this.reportReader = reportReader;
+ this.scmAccountToUser = scmAccountToUser;
+ this.defaultAssigne = defaultAssigne;
+ }
+
+ @Override
+ public void beforeComponent(Component component, Tracking tracking) {
+ // optimization - do not load data if there are no new issues
+ if (!tracking.getUnmatchedRaws().isEmpty()) {
+ scmChangesets = loadScmChangesetsFromReport(component);
+ if (scmChangesets == null) {
+ scmChangesets = loadScmChangesetsFromIndex(component);
+ }
+ computeLastCommitDateAndAuthor();
+ }
+ }
+
+ @Override
+ public void onIssue(Component component, DefaultIssue issue) {
+ if (issue.isNew()) {
+ String scmAuthor = guessScmAuthor(issue.line());
+ issue.setAuthorLogin(scmAuthor);
+ if (scmAuthor != null) {
+ String assigneeLogin = scmAccountToUser.getNullable(scmAuthor);
+ if (assigneeLogin == null) {
+ issue.setAssignee(defaultAssigne.getLogin());
+ } else {
+ issue.setAssignee(assigneeLogin);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void afterComponent(Component component) {
+ lastCommitDate = 0L;
+ lastCommitAuthor = null;
+ scmChangesets = null;
+ }
+
+ /**
+ * Get the SCM login of the last committer on the line. When line is zero,
+ * then get the last committer on the file.
+ */
+ @CheckForNull
+ private String guessScmAuthor(@Nullable Integer line) {
+ String author = null;
+ if (line != null && line <= scmChangesets.getChangesetIndexByLineCount()) {
+ BatchReport.Changesets.Changeset changeset = scmChangesets.getChangeset(scmChangesets.getChangesetIndexByLine(line - 1));
+ author = changeset.hasAuthor() ? changeset.getAuthor() : null;
+ }
+ return StringUtils.defaultIfEmpty(author, lastCommitAuthor);
+ }
+
+ private BatchReport.Changesets loadScmChangesetsFromReport(Component component) {
+ return reportReader.readChangesets(component.getRef());
+ }
+
+ private BatchReport.Changesets loadScmChangesetsFromIndex(Component component) {
+ List<SourceLineDoc> lines = sourceLineIndex.getLines(component.getUuid());
+ Map<String, BatchReport.Changesets.Changeset> changesetByRevision = new HashMap<>();
+ BatchReport.Changesets.Builder scmBuilder = BatchReport.Changesets.newBuilder()
+ .setComponentRef(component.getRef());
+ for (SourceLineDoc sourceLine : lines) {
+ String scmRevision = sourceLine.scmRevision();
+ if (scmRevision == null || changesetByRevision.get(scmRevision) == null) {
+ BatchReport.Changesets.Changeset.Builder changeSetBuilder = BatchReport.Changesets.Changeset.newBuilder();
+ String scmAuthor = sourceLine.scmAuthor();
+ if (scmAuthor != null) {
+ changeSetBuilder.setAuthor(scmAuthor);
+ }
+ Date scmDate = sourceLine.scmDate();
+ if (scmDate != null) {
+ changeSetBuilder.setDate(scmDate.getTime());
+ }
+ if (scmRevision != null) {
+ changeSetBuilder.setRevision(scmRevision);
+ }
+
+ BatchReport.Changesets.Changeset changeset = changeSetBuilder.build();
+ scmBuilder.addChangeset(changeset);
+ scmBuilder.addChangesetIndexByLine(scmBuilder.getChangesetCount() - 1);
+ if (scmRevision != null) {
+ changesetByRevision.put(scmRevision, changeset);
+ }
+ } else {
+ scmBuilder.addChangesetIndexByLine(scmBuilder.getChangesetList().indexOf(changesetByRevision.get(scmRevision)));
+ }
+ }
+ return scmBuilder.build();
+ }
+
+ private void computeLastCommitDateAndAuthor() {
+ for (BatchReport.Changesets.Changeset changeset : scmChangesets.getChangesetList()) {
+ if (changeset.hasAuthor() && changeset.hasDate() && changeset.getDate() > lastCommitDate) {
+ lastCommitDate = changeset.getDate();
+ lastCommitAuthor = changeset.getAuthor();
+ }
+ }
+ }
+}
*/
package org.sonar.server.computation.issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import java.io.File;
+import java.io.IOException;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.TempFolder;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.util.cache.DiskCache;
-import java.io.File;
-import java.io.IOException;
-
/**
* Cache of all the issues involved in the analysis. Their state is as it will be
* persisted in database (after issue tracking, auto-assignment, ...)
+++ /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.
- */
-package org.sonar.server.computation.issue;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.Sets;
-import java.util.Date;
-import javax.annotation.Nullable;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.utils.Duration;
-import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.core.rule.RuleDto;
-import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.ProjectSettingsRepository;
-import org.sonar.server.user.index.UserDoc;
-import org.sonar.server.user.index.UserIndex;
-import org.sonar.server.util.cache.DiskCache;
-
-public class IssueComputation {
-
- private static final Logger LOG = Loggers.get(IssueComputation.class);
-
- private final RuleCache ruleCache;
- private final ScmAccountCache scmAccountCache;
- private final SourceLinesCache linesCache;
- private final DiskCache<DefaultIssue>.DiskAppender diskIssuesAppender;
- private final UserIndex userIndex;
- private final ProjectSettingsRepository projectSettingsRepository;
- private final BatchReportReader reportReader;
- private boolean hasAssigneeBeenComputed = false;
- private String defaultAssignee = null;
-
- public IssueComputation(RuleCache ruleCache, SourceLinesCache linesCache, ScmAccountCache scmAccountCache,
- IssueCache issueCache, UserIndex userIndex, ProjectSettingsRepository projectSettingsRepository, BatchReportReader reportReader) {
- this.ruleCache = ruleCache;
- this.linesCache = linesCache;
- this.scmAccountCache = scmAccountCache;
- this.userIndex = userIndex;
- this.reportReader = reportReader;
- this.projectSettingsRepository = projectSettingsRepository;
- this.diskIssuesAppender = issueCache.newAppender();
- }
-
- public void processComponentIssues(Iterable<BatchReport.Issue> issues, String componentUuid, @Nullable Integer componentReportRef,
- String projectKey, String projectUuid) {
- linesCache.init(componentUuid, componentReportRef, reportReader);
- computeDefaultAssignee(projectSettingsRepository.getProjectSettings(projectKey).getString(CoreProperties.DEFAULT_ISSUE_ASSIGNEE));
- for (BatchReport.Issue reportIssue : issues) {
- DefaultIssue issue = toDefaultIssue(componentUuid, reportIssue, projectKey, projectUuid);
- if (issue.isNew()) {
- guessAuthor(issue);
- autoAssign(issue, defaultAssignee);
- copyRuleTags(issue);
- }
- diskIssuesAppender.append(issue);
- }
- linesCache.clear();
- }
-
- private DefaultIssue toDefaultIssue(String componentUuid, BatchReport.Issue issue, String projectKey, String projectUuid) {
- DefaultIssue target = new DefaultIssue();
- target.setKey(issue.getUuid());
- target.setComponentUuid(componentUuid);
- target.setRuleKey(RuleKey.of(issue.getRuleRepository(), issue.getRuleKey()));
- target.setSeverity(issue.getSeverity().name());
- target.setManualSeverity(issue.getManualSeverity());
- target.setMessage(issue.hasMsg() ? issue.getMsg() : null);
- target.setLine(issue.hasLine() ? issue.getLine() : null);
- target.setProjectUuid(projectUuid);
- target.setProjectKey(projectKey);
- target.setEffortToFix(issue.hasEffortToFix() ? issue.getEffortToFix() : null);
- target.setDebt(issue.hasDebtInMinutes() ? Duration.create(issue.getDebtInMinutes()) : null);
- if (issue.hasDiffFields()) {
- FieldDiffs fieldDiffs = FieldDiffs.parse(issue.getDiffFields());
- fieldDiffs.setCreationDate(new Date(reportReader.readMetadata().getAnalysisDate()));
- target.setCurrentChange(fieldDiffs);
- }
- target.setStatus(issue.getStatus());
- target.setTags(issue.getTagList());
- target.setResolution(issue.hasResolution() ? issue.getResolution() : null);
- target.setReporter(issue.hasReporter() ? issue.getReporter() : null);
- target.setAssignee(issue.hasAssignee() ? issue.getAssignee() : null);
- target.setChecksum(issue.hasChecksum() ? issue.getChecksum() : null);
- target.setAttributes(issue.hasAttributes() ? KeyValueFormat.parse(issue.getAttributes()) : null);
- target.setAuthorLogin(issue.hasAuthorLogin() ? issue.getAuthorLogin() : null);
- target.setActionPlanKey(issue.hasActionPlanKey() ? issue.getActionPlanKey() : null);
- target.setCreationDate(issue.hasCreationDate() ? new Date(issue.getCreationDate()) : null);
- target.setUpdateDate(issue.hasUpdateDate() ? new Date(issue.getUpdateDate()) : null);
- target.setCloseDate(issue.hasCloseDate() ? new Date(issue.getCloseDate()) : null);
- target.setChanged(issue.getIsChanged());
- target.setNew(issue.getIsNew());
- target.setSelectedAt(issue.hasSelectedAt() ? issue.getSelectedAt() : null);
- target.setSendNotifications(issue.getMustSendNotification());
- return target;
- }
-
- public void afterReportProcessing() {
- diskIssuesAppender.close();
- }
-
- private void guessAuthor(DefaultIssue issue) {
- // issue.authorLogin() can be not-null when old developer cockpit plugin (or other plugin)
- // is still installed and executed during analysis
- if (issue.authorLogin() == null) {
- issue.setAuthorLogin(linesCache.lineAuthor(issue.line()));
- }
- }
-
- private void autoAssign(DefaultIssue issue, @Nullable String defaultAssignee) {
- // issue.assignee() can be not-null if the issue-assign-plugin is
- // still installed and executed during analysis
- if (issue.assignee() == null) {
- String scmAccount = issue.authorLogin();
- if (scmAccount != null) {
- issue.setAssignee(scmAccountCache.getNullable(scmAccount));
- }
- if (issue.assignee() == null && defaultAssignee != null) {
- issue.setAssignee(defaultAssignee);
- }
- }
- }
-
- private void copyRuleTags(DefaultIssue issue) {
- RuleDto rule = ruleCache.get(issue.ruleKey());
- issue.setTags(Sets.union(rule.getTags(), rule.getSystemTags()));
- }
-
- private void computeDefaultAssignee(@Nullable String login) {
- if (hasAssigneeBeenComputed) {
- return;
- }
-
- hasAssigneeBeenComputed = true;
- if (!Strings.isNullOrEmpty(login)) {
- UserDoc user = userIndex.getNullableByLogin(login);
- if (user == null) {
- LOG.info("the {} property was set with an unknown login: {}", CoreProperties.DEFAULT_ISSUE_ASSIGNEE, login);
- } else {
- defaultAssignee = login;
- }
- }
- }
-}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import java.util.Date;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.utils.internal.Uuids;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
+import org.sonar.core.issue.IssueUpdater;
+import org.sonar.core.issue.workflow.IssueWorkflow;
+import org.sonar.server.computation.batch.BatchReportReader;
+
+public class IssueLifecycle {
+
+ private final IssueWorkflow workflow;
+ private final IssueChangeContext changeContext;
+ private final IssueUpdater updater;
+
+ public IssueLifecycle(BatchReportReader reportReader, IssueWorkflow workflow, IssueUpdater updater) {
+ this.workflow = workflow;
+ this.updater = updater;
+ this.changeContext = IssueChangeContext.createScan(new Date(reportReader.readMetadata().getAnalysisDate()));
+ }
+
+ public void initNewOpenIssue(DefaultIssue issue) {
+ issue.setKey(Uuids.create());
+ issue.setCreationDate(changeContext.date());
+ issue.setUpdateDate(changeContext.date());
+ issue.setStatus(Issue.STATUS_OPEN);
+ }
+
+ public void mergeExistingOpenIssue(DefaultIssue raw, DefaultIssue base) {
+ raw.setNew(false);
+ raw.setKey(base.key());
+ raw.setCreationDate(base.creationDate());
+ raw.setUpdateDate(base.updateDate());
+ raw.setCloseDate(base.closeDate());
+ raw.setActionPlanKey(base.actionPlanKey());
+ raw.setResolution(base.resolution());
+ raw.setStatus(base.status());
+ raw.setAssignee(base.assignee());
+ raw.setAuthorLogin(base.authorLogin());
+ raw.setTags(base.tags());
+ if (base.manualSeverity()) {
+ raw.setManualSeverity(true);
+ raw.setSeverity(base.severity());
+ } else {
+ updater.setPastSeverity(raw, base.severity(), changeContext);
+ }
+
+ // TODO attributes + changelog
+
+ // fields coming from raw
+ updater.setPastLine(raw, base.getLine());
+ updater.setPastMessage(raw, base.getMessage(), changeContext);
+ updater.setPastEffortToFix(raw, base.effortToFix(), changeContext);
+ updater.setPastTechnicalDebt(raw, base.debt(), changeContext);
+ }
+
+ public void doAutomaticTransition(DefaultIssue issue) {
+ workflow.doAutomaticTransition(issue, changeContext);
+ }
+}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.tracking.Tracking;
+import org.sonar.server.computation.component.Component;
+
+public abstract class IssueListener {
+
+ public void beforeComponent(Component component, Tracking tracking) {
+
+ }
+
+ public void beforeIssue(Component component, DefaultIssue issue) {
+
+ }
+
+ /**
+ * This method is called when tracking is done and issue is initialized. That means that the following fields
+ * are set: resolution, status, line, creation date, uuid and all the fields merged from base issues.
+ */
+ public void onIssue(Component component, DefaultIssue issue) {
+
+ }
+
+ public void afterComponent(Component component) {
+
+ }
+}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.tracking.Tracking;
+import org.sonar.server.computation.component.Component;
+
+public class IssueListeners {
+
+ private final IssueListener[] listeners;
+
+ public IssueListeners(IssueListener[] listeners) {
+ this.listeners = listeners;
+ }
+
+ public void beforeComponent(Component component, Tracking tracking) {
+ for (IssueListener listener : listeners) {
+ listener.beforeComponent(component, tracking);
+ }
+ }
+
+ public void beforeIssue(Component component, DefaultIssue issue) {
+ for (IssueListener listener : listeners) {
+ listener.beforeIssue(component, issue);
+ }
+ }
+
+ public void onIssue(Component component, DefaultIssue issue) {
+ for (IssueListener listener : listeners) {
+ listener.onIssue(component, issue);
+ }
+ }
+
+ public void afterComponent(Component component) {
+ for (IssueListener listener : listeners) {
+ listener.afterComponent(component);
+ }
+ }
+}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.server.computation.component.Component;
+
+public class NewDebtCalculator extends IssueListener {
+
+ @Override
+ public void onIssue(Component component, DefaultIssue issue) {
+ // TODO
+ }
+
+}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import java.util.Set;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.rule.RuleDto;
+import org.sonar.server.computation.component.Component;
+
+import static com.google.common.collect.Sets.union;
+
+public class RuleTagsCopier extends IssueListener {
+
+ private final RuleCache ruleCache;
+
+ public RuleTagsCopier(RuleCache ruleCache) {
+ this.ruleCache = ruleCache;
+ }
+
+ @Override
+ public void onIssue(Component component, DefaultIssue issue) {
+ if (issue.isNew()) {
+ // analyzer can provide some tags. They must be merged with rule tags
+ RuleDto rule = ruleCache.get(issue.ruleKey());
+ Set<String> ruleTags = union(rule.getTags(), rule.getSystemTags());
+ issue.setTags(union(issue.tags(), ruleTags));
+ }
+ }
+}
+++ /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.
- */
-package org.sonar.server.computation.issue;
-
-import org.sonar.server.util.cache.MemoryCache;
-
-/**
- * Cache of dictionary {SCM account -> SQ user login}
- */
-public class ScmAccountCache extends MemoryCache<String,String> {
- public ScmAccountCache(ScmAccountCacheLoader loader) {
- super(loader);
- }
-}
+++ /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.
- */
-package org.sonar.server.computation.issue;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.collect.Collections2;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.server.user.index.UserDoc;
-import org.sonar.server.user.index.UserIndex;
-import org.sonar.server.util.cache.CacheLoader;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Loads the association between a SCM account and a SQ user
- */
-public class ScmAccountCacheLoader implements CacheLoader<String, String> {
-
- private final Logger log;
- private final UserIndex index;
-
- public ScmAccountCacheLoader(UserIndex index) {
- this(index, Loggers.get(ScmAccountCacheLoader.class));
- }
-
- @VisibleForTesting
- ScmAccountCacheLoader(UserIndex index, Logger log) {
- this.log = log;
- this.index = index;
- }
-
- @Override
- public String load(String scmAccount) {
- List<UserDoc> users = index.getAtMostThreeActiveUsersForScmAccount(scmAccount);
- if (users.size() == 1) {
- return users.get(0).login();
- }
- if (!users.isEmpty()) {
- // multiple users are associated to the same SCM account, for example
- // the same email
- Collection<String> logins = Collections2.transform(users, new Function<UserDoc, String>() {
- @Override
- public String apply(UserDoc input) {
- return input.login();
- }
- });
- log.warn(String.format("Multiple users share the SCM account '%s': %s", scmAccount, Joiner.on(", ").join(logins)));
- }
- return null;
- }
-
- @Override
- public Map<String, String> loadAll(Collection<? extends String> scmAccounts) {
- throw new UnsupportedOperationException("Loading by multiple scm accounts is not supported yet");
- }
-}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import org.sonar.server.util.cache.MemoryCache;
+
+/**
+ * Cache of dictionary {SCM account -> SQ user login}. Kept in memory
+ * during the execution of Compute Engine.
+ */
+public class ScmAccountToUser extends MemoryCache<String,String> {
+ public ScmAccountToUser(ScmAccountToUserLoader loader) {
+ super(loader);
+ }
+}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Collections2;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.server.user.index.UserDoc;
+import org.sonar.server.user.index.UserIndex;
+import org.sonar.server.util.cache.CacheLoader;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Loads the association between a SCM account and a SQ user
+ */
+public class ScmAccountToUserLoader implements CacheLoader<String, String> {
+
+ private final Logger log;
+ private final UserIndex index;
+
+ public ScmAccountToUserLoader(UserIndex index) {
+ this(index, Loggers.get(ScmAccountToUserLoader.class));
+ }
+
+ @VisibleForTesting
+ ScmAccountToUserLoader(UserIndex index, Logger log) {
+ this.log = log;
+ this.index = index;
+ }
+
+ @Override
+ public String load(String scmAccount) {
+ List<UserDoc> users = index.getAtMostThreeActiveUsersForScmAccount(scmAccount);
+ if (users.size() == 1) {
+ return users.get(0).login();
+ }
+ if (!users.isEmpty()) {
+ // multiple users are associated to the same SCM account, for example
+ // the same email
+ Collection<String> logins = Collections2.transform(users, new Function<UserDoc, String>() {
+ @Override
+ public String apply(UserDoc input) {
+ return input.login();
+ }
+ });
+ log.warn(String.format("Multiple users share the SCM account '%s': %s", scmAccount, Joiner.on(", ").join(logins)));
+ }
+ return null;
+ }
+
+ @Override
+ public Map<String, String> loadAll(Collection<? extends String> scmAccounts) {
+ throw new UnsupportedOperationException("Loading by multiple scm accounts is not supported yet");
+ }
+}
+++ /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.
- */
-package org.sonar.server.computation.issue;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.batch.protocol.output.BatchReport.Changesets.Changeset;
-import org.sonar.batch.protocol.output.BatchReport.Changesets.Changeset.Builder;
-import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.source.index.SourceLineDoc;
-import org.sonar.server.source.index.SourceLineIndex;
-
-/**
- * Cache of the lines of the currently processed file. Only a <strong>single</strong> file
- * is kept in memory at a time. Data is loaded <strong>on demand</strong> (to avoid non necessary
- * loading).<br />
- * It relies on:
- * <ul>
- * <li>the SCM information sent in the report for modified files</li>
- * <li>the source line index for non-modified files</li>
- * </ul>
- *
- */
-public class SourceLinesCache {
-
- private final SourceLineIndex index;
- private BatchReportReader reportReader;
-
- private boolean loaded = false;
- private BatchReport.Changesets scm;
- private String currentFileUuid;
- private Integer currentFileReportRef;
-
- private long lastCommitDate = 0L;
- private String lastCommitAuthor = null;
-
- public SourceLinesCache(SourceLineIndex index) {
- this.index = index;
- }
-
- /**
- * Marks the currently processed component
- */
- void init(String fileUuid, @Nullable Integer fileReportRef, BatchReportReader reportReader) {
- this.loaded = false;
- this.currentFileUuid = fileUuid;
- this.currentFileReportRef = fileReportRef;
- this.lastCommitDate = 0L;
- this.lastCommitAuthor = null;
- this.reportReader = reportReader;
- clear();
- }
-
- /**
- * Last committer of the line, can be null.
- */
- @CheckForNull
- public String lineAuthor(@Nullable Integer lineNumber) {
- loadIfNeeded();
-
- if (lineNumber == null) {
- // issue on file, approximately estimate that author is the last committer on the file
- return lastCommitAuthor;
- }
- String author = null;
- if (lineNumber <= scm.getChangesetIndexByLineCount()) {
- BatchReport.Changesets.Changeset changeset = scm.getChangeset(scm.getChangesetIndexByLine(lineNumber - 1));
- author = changeset.hasAuthor() ? changeset.getAuthor() : null;
- }
-
- return StringUtils.defaultIfEmpty(author, lastCommitAuthor);
- }
-
- private void loadIfNeeded() {
- checkState();
-
- if (!loaded) {
- scm = loadScmFromReport();
- loaded = scm != null;
- }
-
- if (!loaded) {
- scm = loadLinesFromIndexAndBuildScm();
- loaded = true;
- }
-
- computeLastCommitDateAndAuthor();
- }
-
- private BatchReport.Changesets loadScmFromReport() {
- return reportReader.readChangesets(currentFileReportRef);
- }
-
- private BatchReport.Changesets loadLinesFromIndexAndBuildScm() {
- List<SourceLineDoc> lines = index.getLines(currentFileUuid);
- Map<String, BatchReport.Changesets.Changeset> changesetByRevision = new HashMap<>();
- BatchReport.Changesets.Builder scmBuilder = BatchReport.Changesets.newBuilder()
- .setComponentRef(currentFileReportRef);
- for (SourceLineDoc sourceLine : lines) {
- String scmRevision = sourceLine.scmRevision();
- if (scmRevision == null || changesetByRevision.get(scmRevision) == null) {
- Builder changeSetBuilder = BatchReport.Changesets.Changeset.newBuilder();
- String scmAuthor = sourceLine.scmAuthor();
- if (scmAuthor != null) {
- changeSetBuilder.setAuthor(scmAuthor);
- }
- Date scmDate = sourceLine.scmDate();
- if (scmDate != null) {
- changeSetBuilder.setDate(scmDate.getTime());
- }
- if (scmRevision != null) {
- changeSetBuilder.setRevision(scmRevision);
- }
-
- Changeset changeset = changeSetBuilder.build();
- scmBuilder.addChangeset(changeset);
- scmBuilder.addChangesetIndexByLine(scmBuilder.getChangesetCount() - 1);
- if (scmRevision != null) {
- changesetByRevision.put(scmRevision, changeset);
- }
- } else {
- scmBuilder.addChangesetIndexByLine(scmBuilder.getChangesetList().indexOf(changesetByRevision.get(scmRevision)));
- }
- }
- return scmBuilder.build();
- }
-
- private void computeLastCommitDateAndAuthor() {
- for (BatchReport.Changesets.Changeset changeset : scm.getChangesetList()) {
- if (changeset.hasAuthor() && changeset.hasDate() && changeset.getDate() > lastCommitDate) {
- lastCommitDate = changeset.getDate();
- lastCommitAuthor = changeset.getAuthor();
- }
- }
- }
-
- private void checkState() {
- if (currentFileReportRef == null) {
- throw new IllegalStateException("Report component reference must not be null to use the cache");
- }
- }
-
- /**
- * Makes cache eligible to GC
- */
- public void clear() {
- scm = null;
- }
-}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import java.util.List;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.tracking.Input;
+import org.sonar.core.issue.tracking.LazyInput;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.db.DbClient;
+
+/**
+ * Factory of {@link Input} of base data for issue tracking. Data are lazy-loaded.
+ */
+public class TrackerBaseInputFactory {
+
+ private final BaseIssuesLoader baseIssuesLoader;
+ private final DbClient dbClient;
+
+ public TrackerBaseInputFactory(BaseIssuesLoader baseIssuesLoader, DbClient dbClient) {
+ this.baseIssuesLoader = baseIssuesLoader;
+ this.dbClient = dbClient;
+ }
+
+ public Input<DefaultIssue> create(Component component) {
+ return new BaseLazyInput(component);
+ }
+
+ private class BaseLazyInput extends LazyInput<DefaultIssue> {
+ private final Component component;
+
+ private BaseLazyInput(Component component) {
+ this.component = component;
+ }
+
+ @Override
+ protected Iterable<String> loadSourceLines() {
+ DbSession session = dbClient.openSession(false);
+ try {
+ return dbClient.fileSourceDao().selectLineHashes(session, component.getUuid());
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ @Override
+ protected List<DefaultIssue> loadIssues() {
+ return baseIssuesLoader.loadForComponentUuid(component.getUuid());
+ }
+ }
+}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.tracking.Tracker;
+import org.sonar.core.issue.tracking.Tracking;
+import org.sonar.server.computation.component.Component;
+
+public class TrackerExecution {
+
+ private final TrackerBaseInputFactory baseInputFactory;
+ private final TrackerRawInputFactory rawInputFactory;
+ private final Tracker<DefaultIssue, DefaultIssue> tracker;
+
+ public TrackerExecution(TrackerBaseInputFactory baseInputFactory, TrackerRawInputFactory rawInputFactory,
+ Tracker<DefaultIssue, DefaultIssue> tracker) {
+ this.baseInputFactory = baseInputFactory;
+ this.rawInputFactory = rawInputFactory;
+ this.tracker = tracker;
+ }
+
+ public Tracking<DefaultIssue, DefaultIssue> track(Component component) {
+ return tracker.track(rawInputFactory.create(component), baseInputFactory.create(component));
+ }
+}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.List;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.utils.Duration;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.tracking.Input;
+import org.sonar.core.issue.tracking.LazyInput;
+import org.sonar.core.issue.tracking.LineHashSequence;
+import org.sonar.server.computation.batch.BatchReportReader;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.TreeRootHolder;
+
+public class TrackerRawInputFactory {
+
+ private final TreeRootHolder treeRootHolder;
+ private final BatchReportReader reportReader;
+ private final RuleCache ruleCache;
+
+ public TrackerRawInputFactory(TreeRootHolder treeRootHolder, BatchReportReader reportReader, RuleCache ruleCache) {
+ this.treeRootHolder = treeRootHolder;
+ this.reportReader = reportReader;
+ this.ruleCache = ruleCache;
+ }
+
+ public Input<DefaultIssue> create(Component component) {
+ return new RawLazyInput(component);
+ }
+
+ private class RawLazyInput extends LazyInput<DefaultIssue> {
+ private final Component component;
+
+ private RawLazyInput(Component component) {
+ this.component = component;
+ }
+
+ @Override
+ protected Iterable<String> loadSourceLines() {
+ return Lists.newArrayList(reportReader.readFileSource(component.getRef()));
+ }
+
+ @Override
+ protected List<DefaultIssue> loadIssues() {
+ List<BatchReport.Issue> reportIssues = reportReader.readComponentIssues(component.getRef());
+ List<DefaultIssue> issues = new ArrayList<>();
+ if (!reportIssues.isEmpty()) {
+ // optimization - do not load line hashes if there are no issues
+ LineHashSequence lineHashSeq = getLineHashSequence();
+ for (BatchReport.Issue reportIssue : reportIssues) {
+ DefaultIssue issue = toIssue(lineHashSeq, reportIssue);
+ if (isValid(issue, lineHashSeq)) {
+ issues.add(issue);
+ }
+ }
+ }
+ return issues;
+ }
+
+ private DefaultIssue toIssue(LineHashSequence lineHashSeq, BatchReport.Issue reportIssue) {
+ DefaultIssue issue = new DefaultIssue();
+ issue.setRuleKey(RuleKey.of(reportIssue.getRuleRepository(), reportIssue.getRuleKey()));
+ issue.setStatus(Issue.STATUS_OPEN);
+ issue.setComponentUuid(component.getUuid());
+ issue.setComponentKey(component.getKey());
+ issue.setProjectUuid(treeRootHolder.getRoot().getUuid());
+
+ if (reportIssue.hasLine()) {
+ issue.setLine(reportIssue.getLine());
+ issue.setChecksum(lineHashSeq.getHashForLine(reportIssue.getLine()));
+ } else {
+ issue.setChecksum("");
+ }
+ if (reportIssue.hasMsg()) {
+ issue.setMessage(reportIssue.getMsg());
+ }
+ if (reportIssue.hasSeverity()) {
+ issue.setSeverity(reportIssue.getSeverity().name());
+ }
+ if (reportIssue.hasEffortToFix()) {
+ issue.setEffortToFix(reportIssue.getEffortToFix());
+ }
+ if (reportIssue.hasDebtInMinutes()) {
+ issue.setDebt(Duration.create(reportIssue.getDebtInMinutes()));
+ }
+ issue.setTags(Sets.newHashSet(reportIssue.getTagList()));
+ // TODO issue attributes
+ return issue;
+ }
+ }
+
+ private boolean isValid(DefaultIssue issue, LineHashSequence lineHashSeq) {
+ // TODO log debug when invalid ?
+ if (ruleCache.getNullable(issue.ruleKey()) == null) {
+ return false;
+ }
+ if (issue.getLine() != null && !lineHashSeq.hasLine(issue.getLine())) {
+ return false;
+ }
+ return true;
+ }
+}
import java.util.Arrays;
import java.util.List;
import org.sonar.server.computation.container.ComputeEngineContainer;
+import org.sonar.server.computation.issue.IntegrateIssuesStep;
/**
* Ordered list of steps to be executed
FeedDebtModelStep.class,
- // Read report
- ParseReportStep.class,
-
// load project related stuffs
+ IntegrateIssuesStep.class,
QualityGateLoadingStep.class,
FeedPeriodsStep.class,
+++ /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.
- */
-
-package org.sonar.server.computation.step;
-
-import java.util.List;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
-import org.sonar.server.computation.component.TreeRootHolder;
-import org.sonar.server.computation.issue.IssueComputation;
-
-public class ParseReportStep implements ComputationStep {
-
- private final IssueComputation issueComputation;
- private final BatchReportReader reportReader;
- private final TreeRootHolder treeRootHolder;
-
- public ParseReportStep(IssueComputation issueComputation, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
- this.issueComputation = issueComputation;
- this.reportReader = reportReader;
- this.treeRootHolder = treeRootHolder;
- }
-
- @Override
- public void execute() {
- IssueDepthTraversalTypeAwareVisitor visitor = new IssueDepthTraversalTypeAwareVisitor();
- visitor.visit(treeRootHolder.getRoot());
- processDeletedComponents(visitor);
- issueComputation.afterReportProcessing();
- }
-
- private void processDeletedComponents(IssueDepthTraversalTypeAwareVisitor visitor) {
- int deletedComponentsCount = reportReader.readMetadata().getDeletedComponentsCount();
- for (int componentRef = 1; componentRef <= deletedComponentsCount; componentRef++) {
- BatchReport.Issues issues = reportReader.readDeletedComponentIssues(componentRef);
- issueComputation.processComponentIssues(issues.getIssueList(), issues.getComponentUuid(), null, visitor.projectKey, visitor.projectUuid);
- }
- }
-
- @Override
- public String getDescription() {
- return "Digest analysis report";
- }
-
- private class IssueDepthTraversalTypeAwareVisitor extends DepthTraversalTypeAwareVisitor {
- private String projectKey;
- private String projectUuid;
-
- public IssueDepthTraversalTypeAwareVisitor() {
- super(Component.Type.FILE, Order.PRE_ORDER);
- }
-
- @Override
- public void visitProject(Component tree) {
- projectKey = tree.getKey();
- projectUuid = tree.getUuid();
- executeForComponent(tree);
- }
-
- @Override
- public void visitModule(Component module) {
- executeForComponent(module);
- }
-
- @Override
- public void visitDirectory(Component directory) {
- executeForComponent(directory);
- }
-
- @Override
- public void visitFile(Component file) {
- executeForComponent(file);
- }
-
- private void executeForComponent(Component component) {
- int componentRef = component.getRef();
- List<BatchReport.Issue> issues = reportReader.readComponentIssues(componentRef);
- issueComputation.processComponentIssues(issues, component.getUuid(), componentRef, projectKey, projectUuid);
- }
- }
-}
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.IssueComment;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.FieldDiffs;
import org.sonar.api.utils.System2;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.core.issue.db.IssueChangeDto;
import org.sonar.core.issue.db.IssueChangeMapper;
import org.sonar.core.issue.db.IssueDto;
import java.util.Date;
import java.util.Map;
import java.util.Set;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.api.server.ServerSide;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.condition.IsUnResolved;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.server.rule.RuleTagFormat;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.server.user.UserSession;
import org.sonar.api.server.ServerSide;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.condition.Condition;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.server.user.UserSession;
import java.util.Collection;
import org.sonar.api.issue.action.Action;
import org.sonar.api.issue.action.Actions;
import org.sonar.api.issue.action.Function;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.core.issue.db.IssueStorage;
import org.sonar.core.persistence.DbSession;
import org.sonar.api.server.ServerSide;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.condition.IsUnResolved;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.user.User;
import org.sonar.api.user.UserFinder;
import org.sonar.core.issue.IssueUpdater;
import java.util.Collection;
import java.util.Map;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.server.ServerSide;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.server.user.UserSession;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.IssueComment;
import org.sonar.api.issue.action.Action;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.server.ServerSide;
import org.sonar.api.user.User;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.Rule;
import org.sonar.api.utils.log.Logger;
package org.sonar.server.issue;
import com.google.common.collect.Maps;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.user.User;
import javax.annotation.CheckForNull;
import java.util.Map;
import org.sonar.api.server.ServerSide;
import org.sonar.api.i18n.I18n;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.utils.Duration;
import org.sonar.api.utils.Durations;
import org.sonar.core.issue.IssueUpdater;
import java.util.List;
import org.sonar.api.server.ServerSide;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.user.User;
import org.sonar.api.user.UserFinder;
import org.sonar.core.issue.db.IssueChangeDao;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.server.ServerSide;
import org.sonar.api.issue.IssueComment;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.api.utils.System2;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.core.issue.db.IssueChangeDto;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.issue.ActionPlan;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.server.notification.NotificationManager;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.issue.ActionPlan;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.condition.IsUnResolved;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.server.issue.actionplan.ActionPlanService;
import org.sonar.server.user.UserSession;
package org.sonar.server.issue;
import org.sonar.api.server.ServerSide;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rules.RuleFinder;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.issue.db.IssueDto;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.condition.Condition;
import org.sonar.api.issue.condition.IsUnResolved;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.server.ServerSide;
import org.sonar.api.web.UserRole;
import org.sonar.core.issue.IssueUpdater;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.server.ServerSide;
import org.sonar.core.issue.workflow.IssueWorkflow;
import org.sonar.core.issue.workflow.Transition;
import java.util.List;
import javax.annotation.CheckForNull;
import org.sonar.api.issue.ActionPlan;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.api.server.ServerSide;
import org.sonar.api.web.UserRole;
import org.sonar.core.issue.ActionPlanDeadlineComparator;
*/
package org.sonar.server.issue.db;
-import org.apache.ibatis.session.ResultHandler;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.CheckForNull;
import org.sonar.core.issue.db.IssueDto;
import org.sonar.core.issue.db.IssueMapper;
import org.sonar.core.persistence.DaoComponent;
import org.sonar.core.persistence.MyBatis;
import org.sonar.server.exceptions.NotFoundException;
-import javax.annotation.CheckForNull;
-import java.util.List;
-
public class IssueDao extends org.sonar.core.issue.db.IssueDao implements DaoComponent {
public IssueDao(MyBatis mybatis) {
return mapper(session).selectByKeys(keys);
}
- public void selectNonClosedIssuesByModuleUuid(DbSession session, String moduleUuid, ResultHandler handler) {
- session.select("org.sonar.core.issue.db.IssueMapper.selectNonClosedIssuesByModuleUuid", moduleUuid, handler);
- }
-
- public void selectNonClosedIssuesByProjectUuid(DbSession session, String projectUuid, ResultHandler handler) {
- session.select("org.sonar.core.issue.db.IssueMapper.selectNonClosedIssuesByProjectUuid", projectUuid, handler);
+ public Set<String> selectComponentUuidsOfOpenIssuesForProjectUuid(DbSession session, String projectUuid) {
+ return mapper(session).selectComponentUuidsOfOpenIssuesForProjectUuid(projectUuid);
}
public void insert(DbSession session, IssueDto dto) {
import com.google.common.base.Strings;
import org.sonar.api.component.Component;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.notifications.Notification;
import javax.annotation.CheckForNull;
import org.sonar.api.issue.ActionPlan;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.IssueComment;
-import org.sonar.api.issue.internal.DefaultIssueComment;
import org.sonar.api.user.User;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.Duration;
import org.sonar.api.utils.Durations;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.issue.DefaultIssueComment;
import org.sonar.markdown.Markdown;
import org.sonar.server.user.UserSession;
import org.sonar.server.ws.JsonWriterUtils;
import org.sonar.api.i18n.I18n;
import org.sonar.api.issue.ActionPlan;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssueComment;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.issue.DefaultIssueComment;
import org.sonar.core.persistence.DbSession;
import org.sonar.server.component.ws.ComponentJsonWriter;
import org.sonar.server.db.DbClient;
import org.sonar.api.issue.ActionPlan;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.IssueComment;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.server.debt.DebtCharacteristic;
import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic;
import org.sonar.api.server.ws.Request;
package org.sonar.server.source.db;
import com.google.common.base.Function;
+import com.google.common.base.Splitter;
import java.io.Reader;
import java.sql.Connection;
import java.sql.PreparedStatement;
@ServerSide
public class FileSourceDao implements DaoComponent {
+ private static final Splitter END_OF_LINE_SPLITTER = Splitter.on('\n');
private final MyBatis mybatis;
public FileSourceDao(MyBatis myBatis) {
}
}
+ @CheckForNull
+ public Iterable<String> selectLineHashes(DbSession dbSession, String fileUuid) {
+ Connection connection = dbSession.getConnection();
+ PreparedStatement pstmt = null;
+ ResultSet rs = null;
+ try {
+ pstmt = connection.prepareStatement("SELECT line_hashes FROM file_sources WHERE file_uuid=? AND data_type=?");
+ pstmt.setString(1, fileUuid);
+ pstmt.setString(2, Type.SOURCE);
+ rs = pstmt.executeQuery();
+ if (rs.next()) {
+ return END_OF_LINE_SPLITTER.split(rs.getString(1));
+ }
+ return null;
+ } catch (SQLException e) {
+ throw new IllegalStateException("Fail to read FILE_SOURCES.LINE_HASHES of file " + fileUuid, e);
+ } finally {
+ DbUtils.closeQuietly(connection, pstmt, rs);
+ }
+ }
+
public <T> void readLineHashesStream(DbSession dbSession, String fileUuid, Function<Reader, T> function) {
Connection connection = dbSession.getConnection();
PreparedStatement pstmt = null;
private static final BatchReport.Measure MEASURE = BatchReport.Measure.newBuilder().build();
private static final BatchReport.Component COMPONENT = BatchReport.Component.newBuilder().setRef(COMPONENT_REF).build();
private static final BatchReport.Issue ISSUE = BatchReport.Issue.newBuilder().build();
- private static final BatchReport.Issues ISSUES = BatchReport.Issues.newBuilder().setComponentRef(COMPONENT_REF).setComponentUuid(COMPONENT_UUID).addIssue(ISSUE).build();
+ private static final BatchReport.Issues ISSUES = BatchReport.Issues.newBuilder().setComponentRef(COMPONENT_REF).addIssue(ISSUE).build();
private static final BatchReport.Duplication DUPLICATION = BatchReport.Duplication.newBuilder().build();
private static final BatchReport.Symbols.Symbol SYMBOL = BatchReport.Symbols.Symbol.newBuilder().build();
private static final BatchReport.SyntaxHighlighting SYNTAX_HIGHLIGHTING_1 = BatchReport.SyntaxHighlighting.newBuilder().build();
assertThat(underTest.readComponentIssues(COMPONENT_REF)).isNotSameAs(underTest.readComponentIssues(COMPONENT_REF));
}
- @Test(expected = IllegalStateException.class)
- public void readDeletedComponentIssues_throws_ISE_if_file_does_not_exist() {
- underTest.readDeletedComponentIssues(COMPONENT_REF);
- }
-
- @Test
- public void verify_readDeletedComponentIssues_returns_Issues() {
- writer.writeDeletedComponentIssues(COMPONENT_REF, COMPONENT_UUID, of(ISSUE));
-
- assertThat(underTest.readDeletedComponentIssues(COMPONENT_REF)).isEqualTo(ISSUES);
- }
-
- @Test
- public void readDeletedComponentIssues_it_not_cached() {
- writer.writeDeletedComponentIssues(COMPONENT_REF, COMPONENT_UUID, of(ISSUE));
-
- assertThat(underTest.readDeletedComponentIssues(COMPONENT_REF)).isNotSameAs(underTest.readDeletedComponentIssues(COMPONENT_REF));
- }
-
@Test
public void readComponentDuplications_returns_empty_list_if_file_does_not_exist() {
assertThat(underTest.readComponentDuplications(COMPONENT_REF)).isEmpty();
private Map<Integer, BatchReport.Changesets> changesets = new HashMap<>();
private Map<Integer, BatchReport.Component> components = new HashMap<>();
private Map<Integer, List<BatchReport.Issue>> issues = new HashMap<>();
- private Map<Integer, BatchReport.Issues> deletedIssues = new HashMap<>();
private Map<Integer, List<BatchReport.Duplication>> duplications = new HashMap<>();
private Map<Integer, List<BatchReport.Symbols.Symbol>> symbols = new HashMap<>();
private Map<Integer, List<BatchReport.SyntaxHighlighting>> syntaxHighlightings = new HashMap<>();
public void evaluate() throws Throwable {
try {
statement.evaluate();
- }
- finally {
+ } finally {
clear();
}
}
this.changesets.clear();
this.components.clear();
this.issues.clear();
- this.deletedIssues.clear();
this.duplications.clear();
this.symbols.clear();
this.syntaxHighlightings.clear();
this.issues.put(componentRef, issue);
}
- @Override
- public BatchReport.Issues readDeletedComponentIssues(int deletedComponentRef) {
- BatchReport.Issues issues = this.deletedIssues.get(deletedComponentRef);
- if (issues == null) {
- throw new IllegalStateException("Unable to issues for deleted component #" + deletedComponentRef);
- }
- return issues;
- }
-
- public void putDeletedIssues(int componentRef, BatchReport.Issues issues) {
- this.deletedIssues.put(componentRef, issues);
- }
-
@Override
public List<BatchReport.Duplication> readComponentDuplications(int componentRef) {
return nonNull(this.duplications.get(componentRef));
* 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 com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterators;
-import java.io.IOException;
-import java.util.Arrays;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.utils.System2;
-import org.sonar.api.utils.log.LogTester;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.core.rule.RuleDto;
-import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.component.ProjectSettingsRepository;
-import org.sonar.server.user.index.UserDoc;
-import org.sonar.server.user.index.UserIndex;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class IssueComputationTest {
-
- private static final RuleKey RULE_KEY = RuleKey.of("squid", "R1");
- private static final String PROJECT_KEY = "PROJECT_KEY";
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
- @Rule
- public LogTester logTester = new LogTester();
- @Rule
- public BatchReportReaderRule reportReader = new BatchReportReaderRule();
-
- IssueComputation sut;
-
- // inputs
- RuleCache ruleCache = mock(RuleCache.class);
- SourceLinesCache lineCache = mock(SourceLinesCache.class);
- ScmAccountCache scmAccountCache = mock(ScmAccountCache.class);
- RuleDto rule = new RuleDto().setRepositoryKey(RULE_KEY.repository()).setRuleKey(RULE_KEY.rule());
- BatchReport.Issue.Builder inputIssue = BatchReport.Issue.newBuilder()
- .setUuid("ISSUE_A")
- .setRuleRepository(RULE_KEY.repository())
- .setRuleKey(RULE_KEY.rule())
- .setStatus(Issue.STATUS_OPEN);
- Settings projectSettings;
- ProjectSettingsRepository projectSettingsRepository = mock(ProjectSettingsRepository.class);
- UserIndex userIndex = mock(UserIndex.class);
-
- // output
- IssueCache outputIssues;
-
- @Before
- public void setUp() throws IOException {
- when(ruleCache.get(RULE_KEY)).thenReturn(rule);
- outputIssues = new IssueCache(temp.newFile(), System2.INSTANCE);
- projectSettings = new Settings();
- when(projectSettingsRepository.getProjectSettings(PROJECT_KEY)).thenReturn(projectSettings);
- sut = new IssueComputation(ruleCache, lineCache, scmAccountCache, outputIssues, userIndex, projectSettingsRepository, reportReader);
- }
-
- @After
- public void after() {
- sut.afterReportProcessing();
- }
-
- @Test
- public void store_issues_on_disk() {
- process();
-
- assertThat(Iterators.getOnlyElement(outputIssues.traverse()).key()).isEqualTo("ISSUE_A");
- }
-
- @Test
- public void copy_rule_tags_on_new_issues() {
- inputIssue.setIsNew(true);
- rule.setTags(ImmutableSet.of("bug", "performance"));
- rule.setSystemTags(ImmutableSet.of("blocker"));
-
- process();
-
- assertThat(Iterators.getOnlyElement(outputIssues.traverse()).tags()).containsOnly("blocker", "bug", "performance");
- }
-
- @Test
- public void do_not_copy_rule_tags_on_existing_issues() {
- inputIssue.setIsNew(false);
- rule.setTags(ImmutableSet.of("bug", "performance"));
- rule.setSystemTags(ImmutableSet.of("blocker"));
-
- process();
-
- assertThat(Iterators.getOnlyElement(outputIssues.traverse()).tags()).isEmpty();
- }
-
- @Test
- public void guess_author_of_new_issues() {
- inputIssue.setIsNew(true);
- inputIssue.setLine(3);
- when(lineCache.lineAuthor(3)).thenReturn("charlie");
-
- process();
-
- assertThat(Iterators.getOnlyElement(outputIssues.traverse()).authorLogin()).isEqualTo("charlie");
- }
-
- @Test
- public void do_not_fail_if_missing_author_for_new_issues() {
- inputIssue.setIsNew(true);
- inputIssue.setLine(3);
- when(lineCache.lineAuthor(3)).thenReturn(null);
-
- process();
-
- assertThat(Iterators.getOnlyElement(outputIssues.traverse()).authorLogin()).isNull();
- }
-
- @Test
- public void do_not_guess_author_of_existing_issues() {
- inputIssue.setIsNew(false);
- inputIssue.setLine(3);
- when(lineCache.lineAuthor(3)).thenReturn("charlie");
-
- process();
-
- assertThat(Iterators.getOnlyElement(outputIssues.traverse()).authorLogin()).isNull();
- }
-
- @Test
- public void auto_assign_new_issues() {
- inputIssue.setIsNew(true);
- inputIssue.setAuthorLogin("charlie");
- when(scmAccountCache.getNullable("charlie")).thenReturn("char.lie");
-
- process();
-
- assertThat(Iterators.getOnlyElement(outputIssues.traverse()).assignee()).isEqualTo("char.lie");
- }
-
- @Test
- public void do_not_auto_assign_existing_issues() {
- inputIssue.setIsNew(false);
- inputIssue.setAuthorLogin("charlie");
- when(scmAccountCache.getNullable("charlie")).thenReturn("char.lie");
-
- process();
-
- assertThat(Iterators.getOnlyElement(outputIssues.traverse()).assignee()).isNull();
- }
-
- @Test
- public void do_not_override_author_and_assignee_set_by_old_batch_plugins() {
- inputIssue.setIsNew(true);
-
- // these fields were provided during project analysis, for instance
- // by developer cockpit or issue-assign plugins
- inputIssue.setAuthorLogin("charlie");
- inputIssue.setAssignee("cabu");
-
- process();
-
- // keep the values, without trying to update them
- DefaultIssue cachedIssue = Iterators.getOnlyElement(outputIssues.traverse());
- assertThat(cachedIssue.assignee()).isEqualTo("cabu");
- assertThat(cachedIssue.authorLogin()).isEqualTo("charlie");
- verifyZeroInteractions(scmAccountCache);
- }
-
- @Test
- public void assign_default_assignee_when_available() {
- inputIssue.setIsNew(true);
- String wolinski = "wolinski";
- projectSettings.setProperty(CoreProperties.DEFAULT_ISSUE_ASSIGNEE, wolinski);
- when(userIndex.getNullableByLogin(wolinski)).thenReturn(new UserDoc());
-
- process();
-
- assertThat(Iterators.getOnlyElement(outputIssues.traverse()).assignee()).isEqualTo(wolinski);
- assertThat(logTester.logs()).doesNotContain(String.format("the %s property was set with an unknown login: %s", CoreProperties.DEFAULT_ISSUE_ASSIGNEE, wolinski));
- }
-
- @Test
- public void do_not_assign_default_assignee_when_not_found_in_index() {
- inputIssue.setIsNew(true);
- String wolinski = "wolinski";
- projectSettings.setProperty(CoreProperties.DEFAULT_ISSUE_ASSIGNEE, wolinski);
- when(userIndex.getNullableByLogin(wolinski)).thenReturn(null);
-
- process();
-
- assertThat(Iterators.getOnlyElement(outputIssues.traverse()).assignee()).isNull();
- assertThat(logTester.logs()).contains(String.format("the %s property was set with an unknown login: %s", CoreProperties.DEFAULT_ISSUE_ASSIGNEE, wolinski));
- }
-
- private void process() {
- sut.processComponentIssues(Arrays.asList(inputIssue.build()), "FILE_A", 1, PROJECT_KEY, "PROJECT_UUID");
- }
-}
+///*
+// * 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.
+// */
+//package org.sonar.server.computation.issue;
+//
+//import com.google.common.collect.ImmutableSet;
+//import com.google.common.collect.Iterators;
+//import java.io.IOException;
+//import java.util.Arrays;
+//import org.junit.After;
+//import org.junit.Before;
+//import org.junit.Rule;
+//import org.junit.Test;
+//import org.junit.rules.TemporaryFolder;
+//import org.sonar.api.CoreProperties;
+//import org.sonar.api.config.Settings;
+//import org.sonar.api.issue.Issue;
+//import org.sonar.core.issue.DefaultIssue;
+//import org.sonar.api.rule.RuleKey;
+//import org.sonar.api.utils.System2;
+//import org.sonar.api.utils.log.LogTester;
+//import org.sonar.batch.protocol.output.BatchReport;
+//import org.sonar.core.rule.RuleDto;
+//import org.sonar.server.computation.batch.BatchReportReaderRule;
+//import org.sonar.server.computation.component.ProjectSettingsRepository;
+//import org.sonar.server.user.index.UserDoc;
+//import org.sonar.server.user.index.UserIndex;
+//
+//import static org.assertj.core.api.Assertions.assertThat;
+//import static org.mockito.Mockito.mock;
+//import static org.mockito.Mockito.verifyZeroInteractions;
+//import static org.mockito.Mockito.when;
+//
+//public class IssueComputationTest {
+//
+// private static final RuleKey RULE_KEY = RuleKey.of("squid", "R1");
+// private static final String PROJECT_KEY = "PROJECT_KEY";
+//
+// @Rule
+// public TemporaryFolder temp = new TemporaryFolder();
+// @Rule
+// public LogTester logTester = new LogTester();
+// @Rule
+// public BatchReportReaderRule reportReader = new BatchReportReaderRule();
+//
+// IssueComputation sut;
+//
+// // inputs
+// RuleCache ruleCache = mock(RuleCache.class);
+// SourceAuthorsHolder lineCache = mock(SourceAuthorsHolder.class);
+// ScmAccountToUser scmAccountToUser = mock(ScmAccountToUser.class);
+// RuleDto rule = new RuleDto().setRepositoryKey(RULE_KEY.repository()).setRuleKey(RULE_KEY.rule());
+// BatchReport.Issue.Builder inputIssue = BatchReport.Issue.newBuilder()
+// .setUuid("ISSUE_A")
+// .setRuleRepository(RULE_KEY.repository())
+// .setRuleKey(RULE_KEY.rule())
+// .setStatus(Issue.STATUS_OPEN);
+// Settings projectSettings;
+// ProjectSettingsRepository projectSettingsRepository = mock(ProjectSettingsRepository.class);
+// UserIndex userIndex = mock(UserIndex.class);
+//
+// // output
+// DeprecatedIssueCache outputIssues;
+//
+// @Before
+// public void setUp() throws IOException {
+// when(ruleCache.get(RULE_KEY)).thenReturn(rule);
+// outputIssues = new DeprecatedIssueCache(temp.newFile(), System2.INSTANCE);
+// projectSettings = new Settings();
+// when(projectSettingsRepository.getProjectSettings(PROJECT_KEY)).thenReturn(projectSettings);
+// sut = new IssueComputation(ruleCache, lineCache, scmAccountToUser, outputIssues, userIndex, projectSettingsRepository, reportReader);
+// }
+//
+// @After
+// public void after() {
+// sut.afterReportProcessing();
+// }
+//
+// @Test
+// public void store_issues_on_disk() {
+// process();
+//
+// assertThat(Iterators.getOnlyElement(outputIssues.traverse()).key()).isEqualTo("ISSUE_A");
+// }
+//
+// @Test
+// public void copy_rule_tags_on_new_issues() {
+// inputIssue.setIsNew(true);
+// rule.setTags(ImmutableSet.of("bug", "performance"));
+// rule.setSystemTags(ImmutableSet.of("blocker"));
+//
+// process();
+//
+// assertThat(Iterators.getOnlyElement(outputIssues.traverse()).tags()).containsOnly("blocker", "bug", "performance");
+// }
+//
+// @Test
+// public void do_not_copy_rule_tags_on_existing_issues() {
+// inputIssue.setIsNew(false);
+// rule.setTags(ImmutableSet.of("bug", "performance"));
+// rule.setSystemTags(ImmutableSet.of("blocker"));
+//
+// process();
+//
+// assertThat(Iterators.getOnlyElement(outputIssues.traverse()).tags()).isEmpty();
+// }
+//
+// @Test
+// public void guess_author_of_new_issues() {
+// inputIssue.setIsNew(true);
+// inputIssue.setLine(3);
+// when(lineCache.lineAuthor(3)).thenReturn("charlie");
+//
+// process();
+//
+// assertThat(Iterators.getOnlyElement(outputIssues.traverse()).authorLogin()).isEqualTo("charlie");
+// }
+//
+// @Test
+// public void do_not_fail_if_missing_author_for_new_issues() {
+// inputIssue.setIsNew(true);
+// inputIssue.setLine(3);
+// when(lineCache.lineAuthor(3)).thenReturn(null);
+//
+// process();
+//
+// assertThat(Iterators.getOnlyElement(outputIssues.traverse()).authorLogin()).isNull();
+// }
+//
+// @Test
+// public void do_not_guess_author_of_existing_issues() {
+// inputIssue.setIsNew(false);
+// inputIssue.setLine(3);
+// when(lineCache.lineAuthor(3)).thenReturn("charlie");
+//
+// process();
+//
+// assertThat(Iterators.getOnlyElement(outputIssues.traverse()).authorLogin()).isNull();
+// }
+//
+// @Test
+// public void auto_assign_new_issues() {
+// inputIssue.setIsNew(true);
+// inputIssue.setAuthorLogin("charlie");
+// when(scmAccountToUser.getNullable("charlie")).thenReturn("char.lie");
+//
+// process();
+//
+// assertThat(Iterators.getOnlyElement(outputIssues.traverse()).assignee()).isEqualTo("char.lie");
+// }
+//
+// @Test
+// public void do_not_auto_assign_existing_issues() {
+// inputIssue.setIsNew(false);
+// inputIssue.setAuthorLogin("charlie");
+// when(scmAccountToUser.getNullable("charlie")).thenReturn("char.lie");
+//
+// process();
+//
+// assertThat(Iterators.getOnlyElement(outputIssues.traverse()).assignee()).isNull();
+// }
+//
+// @Test
+// public void do_not_override_author_and_assignee_set_by_old_batch_plugins() {
+// inputIssue.setIsNew(true);
+//
+// // these fields were provided during project analysis, for instance
+// // by developer cockpit or issue-assign plugins
+// inputIssue.setAuthorLogin("charlie");
+// inputIssue.setAssignee("cabu");
+//
+// process();
+//
+// // keep the values, without trying to update them
+// DefaultIssue cachedIssue = Iterators.getOnlyElement(outputIssues.traverse());
+// assertThat(cachedIssue.assignee()).isEqualTo("cabu");
+// assertThat(cachedIssue.authorLogin()).isEqualTo("charlie");
+// verifyZeroInteractions(scmAccountToUser);
+// }
+//
+// @Test
+// public void assign_default_assignee_when_available() {
+// inputIssue.setIsNew(true);
+// String wolinski = "wolinski";
+// projectSettings.setProperty(CoreProperties.DEFAULT_ISSUE_ASSIGNEE, wolinski);
+// when(userIndex.getNullableByLogin(wolinski)).thenReturn(new UserDoc());
+//
+// process();
+//
+// assertThat(Iterators.getOnlyElement(outputIssues.traverse()).assignee()).isEqualTo(wolinski);
+// assertThat(logTester.logs()).doesNotContain(String.format("the %s property was set with an unknown login: %s", CoreProperties.DEFAULT_ISSUE_ASSIGNEE, wolinski));
+// }
+//
+// @Test
+// public void do_not_assign_default_assignee_when_not_found_in_index() {
+// inputIssue.setIsNew(true);
+// String wolinski = "wolinski";
+// projectSettings.setProperty(CoreProperties.DEFAULT_ISSUE_ASSIGNEE, wolinski);
+// when(userIndex.getNullableByLogin(wolinski)).thenReturn(null);
+//
+// process();
+//
+// assertThat(Iterators.getOnlyElement(outputIssues.traverse()).assignee()).isNull();
+// assertThat(logTester.logs()).contains(String.format("the %s property was set with an unknown login: %s", CoreProperties.DEFAULT_ISSUE_ASSIGNEE, wolinski));
+// }
+//
+// private void process() {
+// sut.processComponentIssues(Arrays.asList(inputIssue.build()), "FILE_A", 1, PROJECT_KEY, "PROJECT_UUID");
+// }
+//}
+++ /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.
- */
-package org.sonar.server.computation.issue;
-
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.api.config.Settings;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.user.index.UserIndex;
-import org.sonar.server.user.index.UserIndexDefinition;
-
-import java.util.Collections;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-public class ScmAccountCacheLoaderTest {
-
- @ClassRule
- public static EsTester esTester = new EsTester().addDefinitions(new UserIndexDefinition(new Settings()));
-
- @Before
- public void setUp() {
- esTester.truncateIndices();
- }
-
- @Test
- public void load_login_for_scm_account() throws Exception {
- esTester.putDocuments("users", "user", getClass(), "charlie.json");
- UserIndex index = new UserIndex(esTester.client());
- ScmAccountCacheLoader loader = new ScmAccountCacheLoader(index);
-
- assertThat(loader.load("missing")).isNull();
- assertThat(loader.load("jesuis@charlie.com")).isEqualTo("charlie");
- }
-
- @Test
- public void warn_if_multiple_users_share_same_scm_account() throws Exception {
- esTester.putDocuments("users", "user", getClass(), "charlie.json", "charlie_conflict.json");
- UserIndex index = new UserIndex(esTester.client());
- Logger log = mock(Logger.class);
- ScmAccountCacheLoader loader = new ScmAccountCacheLoader(index, log);
-
- assertThat(loader.load("charlie")).isNull();
- verify(log).warn("Multiple users share the SCM account 'charlie': charlie, another.charlie");
- }
-
- @Test
- public void load_by_multiple_scm_accounts_is_not_supported_yet() {
- UserIndex index = new UserIndex(esTester.client());
- ScmAccountCacheLoader loader = new ScmAccountCacheLoader(index);
- try {
- loader.loadAll(Collections.<String>emptyList());
- fail();
- } catch (UnsupportedOperationException ignored) {
- }
- }
-}
--- /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.
+ */
+package org.sonar.server.computation.issue;
+
+import java.util.Collections;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.user.index.UserIndex;
+import org.sonar.server.user.index.UserIndexDefinition;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class ScmAccountToUserLoaderTest {
+
+ @ClassRule
+ public static EsTester esTester = new EsTester().addDefinitions(new UserIndexDefinition(new Settings()));
+
+ @Before
+ public void setUp() {
+ esTester.truncateIndices();
+ }
+
+ @Test
+ public void load_login_for_scm_account() throws Exception {
+ esTester.putDocuments("users", "user", getClass(), "charlie.json");
+ UserIndex index = new UserIndex(esTester.client());
+ ScmAccountToUserLoader loader = new ScmAccountToUserLoader(index);
+
+ assertThat(loader.load("missing")).isNull();
+ assertThat(loader.load("jesuis@charlie.com")).isEqualTo("charlie");
+ }
+
+ @Test
+ public void warn_if_multiple_users_share_same_scm_account() throws Exception {
+ esTester.putDocuments("users", "user", getClass(), "charlie.json", "charlie_conflict.json");
+ UserIndex index = new UserIndex(esTester.client());
+ Logger log = mock(Logger.class);
+ ScmAccountToUserLoader loader = new ScmAccountToUserLoader(index, log);
+
+ assertThat(loader.load("charlie")).isNull();
+ verify(log).warn("Multiple users share the SCM account 'charlie': charlie, another.charlie");
+ }
+
+ @Test
+ public void load_by_multiple_scm_accounts_is_not_supported_yet() {
+ UserIndex index = new UserIndex(esTester.client());
+ ScmAccountToUserLoader loader = new ScmAccountToUserLoader(index);
+ try {
+ loader.loadAll(Collections.<String>emptyList());
+ fail();
+ } catch (UnsupportedOperationException ignored) {
+ }
+ }
+}
--- /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, 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.
+// */
+//package org.sonar.server.computation.issue;
+//
+//import java.util.Date;
+//import org.junit.Before;
+//import org.junit.ClassRule;
+//import org.junit.Rule;
+//import org.junit.Test;
+//import org.junit.experimental.categories.Category;
+//import org.sonar.api.config.Settings;
+//import org.sonar.batch.protocol.output.BatchReport;
+//import org.sonar.server.computation.batch.BatchReportReaderRule;
+//import org.sonar.server.es.EsTester;
+//import org.sonar.server.source.index.SourceLineDoc;
+//import org.sonar.server.source.index.SourceLineIndex;
+//import org.sonar.server.source.index.SourceLineIndexDefinition;
+//import org.sonar.test.DbTests;
+//
+//import static org.assertj.core.api.Assertions.assertThat;
+//
+//@Category(DbTests.class)
+//public class SourceAuthorsHolderTest {
+//
+// @ClassRule
+// public static EsTester esTester = new EsTester().addDefinitions(new SourceLineIndexDefinition(new Settings()));
+// @Rule
+// public BatchReportReaderRule reportReader = new BatchReportReaderRule();
+//
+// SourceAuthorsHolder sut;
+//
+// @Before
+// public void setUp() throws Exception {
+// esTester.truncateIndices();
+// sut = new SourceAuthorsHolder(new SourceLineIndex(esTester.client()), reportReader);
+// }
+//
+// @Test
+// public void line_author_from_report() {
+// reportReader.putChangesets(BatchReport.Changesets.newBuilder()
+// .setComponentRef(123_456_789)
+// .addChangeset(newChangeset("charb", "123-456-789", 123_456_789L))
+// .addChangeset(newChangeset("wolinski", "987-654-321", 987_654_321L))
+// .addChangesetIndexByLine(0)
+// .addChangesetIndexByLine(0)
+// .addChangesetIndexByLine(1)
+// .build());
+//
+// sut.init("ANY_UUID", 123_456_789, reportReader);
+//
+// assertThat(sut.lineAuthor(1)).isEqualTo("charb");
+// assertThat(sut.lineAuthor(2)).isEqualTo("charb");
+// assertThat(sut.lineAuthor(3)).isEqualTo("wolinski");
+// // compute last author
+// assertThat(sut.lineAuthor(4)).isEqualTo("wolinski");
+// assertThat(sut.lineAuthor(null)).isEqualTo("wolinski");
+// }
+//
+// @Test
+// public void line_author_from_index() throws Exception {
+// esTester.putDocuments(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE,
+// newSourceLine("cabu", "123-456-789", 123_456_789, 1),
+// newSourceLine("cabu", "123-456-789", 123_456_789, 2),
+// newSourceLine("cabu", "123-123-789", 123_456_789, 3),
+// newSourceLine("wolinski", "987-654-321", 987_654_321, 4),
+// newSourceLine("cabu", "123-456-789", 123_456_789, 5)
+// );
+//
+// sut.init("DEFAULT_UUID", 123, reportReader);
+//
+// assertThat(sut.lineAuthor(1)).isEqualTo("cabu");
+// assertThat(sut.lineAuthor(2)).isEqualTo("cabu");
+// assertThat(sut.lineAuthor(3)).isEqualTo("cabu");
+// assertThat(sut.lineAuthor(4)).isEqualTo("wolinski");
+// assertThat(sut.lineAuthor(5)).isEqualTo("cabu");
+// assertThat(sut.lineAuthor(6)).isEqualTo("wolinski");
+// }
+//
+// @Test(expected = IllegalStateException.class)
+// public void fail_when_component_ref_is_not_filled() {
+// sut.init("ANY_UUID", null, reportReader);
+// sut.lineAuthor(0);
+// }
+//
+// private BatchReport.Changesets.Changeset.Builder newChangeset(String author, String revision, long date) {
+// return BatchReport.Changesets.Changeset.newBuilder()
+// .setAuthor(author)
+// .setRevision(revision)
+// .setDate(date);
+// }
+//
+// private SourceLineDoc newSourceLine(String author, String revision, long date, int lineNumber) {
+// return new SourceLineDoc()
+// .setScmAuthor(author)
+// .setScmRevision(revision)
+// .setScmDate(new Date(date))
+// .setLine(lineNumber)
+// .setProjectUuid("PROJECT_UUID")
+// .setFileUuid("DEFAULT_UUID");
+// }
+//}
+++ /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.
- */
-package org.sonar.server.computation.issue;
-
-import java.util.Date;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.sonar.api.config.Settings;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.source.index.SourceLineDoc;
-import org.sonar.server.source.index.SourceLineIndex;
-import org.sonar.server.source.index.SourceLineIndexDefinition;
-import org.sonar.test.DbTests;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-@Category(DbTests.class)
-public class SourceLinesCacheTest {
-
- @ClassRule
- public static EsTester esTester = new EsTester().addDefinitions(new SourceLineIndexDefinition(new Settings()));
- @Rule
- public BatchReportReaderRule reportReader = new BatchReportReaderRule();
-
- SourceLinesCache sut;
-
- @Before
- public void setUp() throws Exception {
- esTester.truncateIndices();
- sut = new SourceLinesCache(new SourceLineIndex(esTester.client()));
- }
-
- @Test
- public void line_author_from_report() {
- reportReader.putChangesets(BatchReport.Changesets.newBuilder()
- .setComponentRef(123_456_789)
- .addChangeset(newChangeset("charb", "123-456-789", 123_456_789L))
- .addChangeset(newChangeset("wolinski", "987-654-321", 987_654_321L))
- .addChangesetIndexByLine(0)
- .addChangesetIndexByLine(0)
- .addChangesetIndexByLine(1)
- .build());
-
- sut.init("ANY_UUID", 123_456_789, reportReader);
-
- assertThat(sut.lineAuthor(1)).isEqualTo("charb");
- assertThat(sut.lineAuthor(2)).isEqualTo("charb");
- assertThat(sut.lineAuthor(3)).isEqualTo("wolinski");
- // compute last author
- assertThat(sut.lineAuthor(4)).isEqualTo("wolinski");
- assertThat(sut.lineAuthor(null)).isEqualTo("wolinski");
- }
-
- @Test
- public void line_author_from_index() throws Exception {
- esTester.putDocuments(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE,
- newSourceLine("cabu", "123-456-789", 123_456_789, 1),
- newSourceLine("cabu", "123-456-789", 123_456_789, 2),
- newSourceLine("cabu", "123-123-789", 123_456_789, 3),
- newSourceLine("wolinski", "987-654-321", 987_654_321, 4),
- newSourceLine("cabu", "123-456-789", 123_456_789, 5)
- );
-
- sut.init("DEFAULT_UUID", 123, reportReader);
-
- assertThat(sut.lineAuthor(1)).isEqualTo("cabu");
- assertThat(sut.lineAuthor(2)).isEqualTo("cabu");
- assertThat(sut.lineAuthor(3)).isEqualTo("cabu");
- assertThat(sut.lineAuthor(4)).isEqualTo("wolinski");
- assertThat(sut.lineAuthor(5)).isEqualTo("cabu");
- assertThat(sut.lineAuthor(6)).isEqualTo("wolinski");
- }
-
- @Test(expected = IllegalStateException.class)
- public void fail_when_component_ref_is_not_filled() {
- sut.init("ANY_UUID", null, reportReader);
- sut.lineAuthor(0);
- }
-
- private BatchReport.Changesets.Changeset.Builder newChangeset(String author, String revision, long date) {
- return BatchReport.Changesets.Changeset.newBuilder()
- .setAuthor(author)
- .setRevision(revision)
- .setDate(date);
- }
-
- private SourceLineDoc newSourceLine(String author, String revision, long date, int lineNumber) {
- return new SourceLineDoc()
- .setScmAuthor(author)
- .setScmRevision(revision)
- .setScmDate(new Date(date))
- .setLine(lineNumber)
- .setProjectUuid("PROJECT_UUID")
- .setFileUuid("DEFAULT_UUID");
- }
-}
+++ /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.
- */
-package org.sonar.server.computation.step;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.batch.protocol.Constants;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.core.persistence.DbTester;
-import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.batch.TreeRootHolderRule;
-import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.DumbComponent;
-import org.sonar.server.computation.issue.IssueComputation;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-public class ParseReportStepTest extends BaseStepTest {
-
- private static final String PROJECT_KEY = "PROJECT_KEY";
-
- private static final List<BatchReport.Issue> ISSUES_ON_DELETED_COMPONENT = Arrays.asList(BatchReport.Issue.newBuilder()
- .setUuid("DELETED_ISSUE_UUID")
- .build());
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
- @Rule
- public BatchReportReaderRule reportReader = new BatchReportReaderRule();
- @Rule
- public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
-
- @ClassRule
- public static DbTester dbTester = new DbTester();
-
- IssueComputation issueComputation = mock(IssueComputation.class);
- ParseReportStep sut = new ParseReportStep(issueComputation, reportReader, treeRootHolder);
-
- @Test
- public void extract_report_from_db_and_browse_components() throws Exception {
- DumbComponent root = DumbComponent.builder(Component.Type.PROJECT, 1).setUuid("PROJECT_UUID").setKey(PROJECT_KEY).addChildren(
- DumbComponent.builder(Component.Type.FILE, 2).setUuid("FILE1_UUID").setKey("PROJECT_KEY:file1").build(),
- DumbComponent.builder(Component.Type.FILE, 3).setUuid("FILE2_UUID").setKey("PROJECT_KEY:file2").build())
- .build();
-
- generateReport();
-
- treeRootHolder.setRoot(root);
-
- sut.execute();
-
- assertThat(reportReader.readMetadata().getRootComponentRef()).isEqualTo(1);
- assertThat(reportReader.readMetadata().getDeletedComponentsCount()).isEqualTo(1);
-
- // verify that all components are processed (currently only for issues)
- verify(issueComputation).processComponentIssues(Collections.<BatchReport.Issue>emptyList(), "PROJECT_UUID", 1, PROJECT_KEY, "PROJECT_UUID");
- verify(issueComputation).processComponentIssues(Collections.<BatchReport.Issue>emptyList(), "FILE1_UUID", 2, PROJECT_KEY, "PROJECT_UUID");
- verify(issueComputation).processComponentIssues(Collections.<BatchReport.Issue>emptyList(), "FILE2_UUID", 3, PROJECT_KEY, "PROJECT_UUID");
- verify(issueComputation).processComponentIssues(ISSUES_ON_DELETED_COMPONENT, "DELETED_UUID", null, PROJECT_KEY, "PROJECT_UUID");
- verify(issueComputation).afterReportProcessing();
- }
-
- private void generateReport() throws IOException {
- // project and 2 files
- reportReader.setMetadata(BatchReport.Metadata.newBuilder()
- .setRootComponentRef(1)
- .setDeletedComponentsCount(1)
- .build());
-
- reportReader.putComponent(BatchReport.Component.newBuilder()
- .setRef(1)
- .setType(Constants.ComponentType.PROJECT)
- .addChildRef(2)
- .addChildRef(3)
- .build());
- reportReader.putComponent(BatchReport.Component.newBuilder()
- .setRef(2)
- .setType(Constants.ComponentType.FILE)
- .build());
- reportReader.putComponent(BatchReport.Component.newBuilder()
- .setRef(3)
- .setType(Constants.ComponentType.FILE)
- .build());
-
- // deleted components
- BatchReport.Issues.Builder issuesBuilder = BatchReport.Issues.newBuilder();
- issuesBuilder.setComponentRef(1);
- issuesBuilder.setComponentUuid("DELETED_UUID");
- issuesBuilder.addAllIssue(ISSUES_ON_DELETED_COMPONENT);
- reportReader.putDeletedIssues(1, issuesBuilder.build());
- }
-
- @Override
- protected ComputationStep step() {
- return sut;
- }
-}
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.FieldDiffs;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.System2;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.core.issue.db.UpdateConflictResolver;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.DbTester;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.notifications.Notification;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.System2;
import org.sonar.api.issue.action.Actions;
import org.sonar.api.issue.action.Function;
import org.sonar.api.issue.condition.Condition;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.core.issue.db.IssueDto;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Matchers;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.issue.IssueUpdater;
import java.util.Collection;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.api.user.User;
import org.sonar.api.user.UserFinder;
import org.sonar.core.issue.IssueUpdater;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.server.tester.AnonymousMockUserSession;
import org.sonar.api.issue.ActionPlan;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.action.Action;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.user.User;
import org.sonar.api.web.UserRole;
import org.sonar.core.issue.DefaultActionPlan;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.api.i18n.I18n;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.utils.Duration;
import org.sonar.api.utils.Durations;
import org.sonar.server.tester.UserSessionRule;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.user.User;
import org.sonar.api.user.UserFinder;
import org.sonar.core.issue.db.IssueChangeDao;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssueComment;
+import org.sonar.core.issue.DefaultIssueComment;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.security.DefaultGroups;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.core.issue.db.IssueChangeDao;
import org.sonar.core.issue.db.IssueChangeDto;
import org.junit.rules.ExpectedException;
import org.sonar.api.issue.ActionPlan;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.issue.DefaultActionPlan;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.server.issue.actionplan.ActionPlanService;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Matchers;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.issue.IssueUpdater;
import java.util.Collection;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.api.web.UserRole;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.server.tester.UserSessionRule;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.issue.workflow.IssueWorkflow;
import org.sonar.core.issue.workflow.Transition;
import org.sonar.server.tester.UserSessionRule;
import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.api.issue.ActionPlan;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.api.web.UserRole;
import org.sonar.core.issue.ActionPlanStats;
import org.sonar.core.issue.DefaultActionPlan;
package org.sonar.server.issue.notification;
import org.junit.Test;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.core.component.ComponentDto;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.Lists;
import org.junit.Test;
import org.mockito.Mockito;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.DateUtils;
import com.google.common.collect.Lists;
import org.junit.Test;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.Duration;
import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.action.Action;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.api.web.UserRole;
import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.api.i18n.I18n;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic;
import org.sonar.api.user.User;
* <code>optional int32 root_component_ref = 4;</code>
*/
int getRootComponentRef();
-
- /**
- * <code>optional int32 deleted_components_count = 5;</code>
- *
- * <pre>
- * temporary fields used during development of computation stack
- * </pre>
- */
- boolean hasDeletedComponentsCount();
- /**
- * <code>optional int32 deleted_components_count = 5;</code>
- *
- * <pre>
- * temporary fields used during development of computation stack
- * </pre>
- */
- int getDeletedComponentsCount();
}
/**
* Protobuf type {@code Metadata}
rootComponentRef_ = input.readInt32();
break;
}
- case 40: {
- bitField0_ |= 0x00000010;
- deletedComponentsCount_ = input.readInt32();
- break;
- }
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
return rootComponentRef_;
}
- public static final int DELETED_COMPONENTS_COUNT_FIELD_NUMBER = 5;
- private int deletedComponentsCount_;
- /**
- * <code>optional int32 deleted_components_count = 5;</code>
- *
- * <pre>
- * temporary fields used during development of computation stack
- * </pre>
- */
- public boolean hasDeletedComponentsCount() {
- return ((bitField0_ & 0x00000010) == 0x00000010);
- }
- /**
- * <code>optional int32 deleted_components_count = 5;</code>
- *
- * <pre>
- * temporary fields used during development of computation stack
- * </pre>
- */
- public int getDeletedComponentsCount() {
- return deletedComponentsCount_;
- }
-
private void initFields() {
analysisDate_ = 0L;
projectKey_ = "";
branch_ = "";
rootComponentRef_ = 0;
- deletedComponentsCount_ = 0;
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
if (((bitField0_ & 0x00000008) == 0x00000008)) {
output.writeInt32(4, rootComponentRef_);
}
- if (((bitField0_ & 0x00000010) == 0x00000010)) {
- output.writeInt32(5, deletedComponentsCount_);
- }
getUnknownFields().writeTo(output);
}
size += com.google.protobuf.CodedOutputStream
.computeInt32Size(4, rootComponentRef_);
}
- if (((bitField0_ & 0x00000010) == 0x00000010)) {
- size += com.google.protobuf.CodedOutputStream
- .computeInt32Size(5, deletedComponentsCount_);
- }
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
bitField0_ = (bitField0_ & ~0x00000004);
rootComponentRef_ = 0;
bitField0_ = (bitField0_ & ~0x00000008);
- deletedComponentsCount_ = 0;
- bitField0_ = (bitField0_ & ~0x00000010);
return this;
}
to_bitField0_ |= 0x00000008;
}
result.rootComponentRef_ = rootComponentRef_;
- if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
- to_bitField0_ |= 0x00000010;
- }
- result.deletedComponentsCount_ = deletedComponentsCount_;
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
if (other.hasRootComponentRef()) {
setRootComponentRef(other.getRootComponentRef());
}
- if (other.hasDeletedComponentsCount()) {
- setDeletedComponentsCount(other.getDeletedComponentsCount());
- }
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
return this;
}
- private int deletedComponentsCount_ ;
- /**
- * <code>optional int32 deleted_components_count = 5;</code>
- *
- * <pre>
- * temporary fields used during development of computation stack
- * </pre>
- */
- public boolean hasDeletedComponentsCount() {
- return ((bitField0_ & 0x00000010) == 0x00000010);
- }
- /**
- * <code>optional int32 deleted_components_count = 5;</code>
- *
- * <pre>
- * temporary fields used during development of computation stack
- * </pre>
- */
- public int getDeletedComponentsCount() {
- return deletedComponentsCount_;
- }
- /**
- * <code>optional int32 deleted_components_count = 5;</code>
- *
- * <pre>
- * temporary fields used during development of computation stack
- * </pre>
- */
- public Builder setDeletedComponentsCount(int value) {
- bitField0_ |= 0x00000010;
- deletedComponentsCount_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional int32 deleted_components_count = 5;</code>
- *
- * <pre>
- * temporary fields used during development of computation stack
- * </pre>
- */
- public Builder clearDeletedComponentsCount() {
- bitField0_ = (bitField0_ & ~0x00000010);
- deletedComponentsCount_ = 0;
- onChanged();
- return this;
- }
-
// @@protoc_insertion_point(builder_scope:Metadata)
}
/**
* <code>optional double effort_to_fix = 7;</code>
- *
- * <pre>
- * temporary fields during development of computation stack
- * </pre>
*/
boolean hasEffortToFix();
/**
* <code>optional double effort_to_fix = 7;</code>
- *
- * <pre>
- * temporary fields during development of computation stack
- * </pre>
*/
double getEffortToFix();
/**
- * <code>optional bool is_new = 8;</code>
- */
- boolean hasIsNew();
- /**
- * <code>optional bool is_new = 8;</code>
- */
- boolean getIsNew();
-
- /**
- * <code>optional string uuid = 9;</code>
- */
- boolean hasUuid();
- /**
- * <code>optional string uuid = 9;</code>
- */
- java.lang.String getUuid();
- /**
- * <code>optional string uuid = 9;</code>
- */
- com.google.protobuf.ByteString
- getUuidBytes();
-
- /**
- * <code>optional int64 debt_in_minutes = 10;</code>
- */
- boolean hasDebtInMinutes();
- /**
- * <code>optional int64 debt_in_minutes = 10;</code>
- */
- long getDebtInMinutes();
-
- /**
- * <code>optional string resolution = 11;</code>
- */
- boolean hasResolution();
- /**
- * <code>optional string resolution = 11;</code>
- */
- java.lang.String getResolution();
- /**
- * <code>optional string resolution = 11;</code>
- */
- com.google.protobuf.ByteString
- getResolutionBytes();
-
- /**
- * <code>optional string status = 12;</code>
- */
- boolean hasStatus();
- /**
- * <code>optional string status = 12;</code>
- */
- java.lang.String getStatus();
- /**
- * <code>optional string status = 12;</code>
- */
- com.google.protobuf.ByteString
- getStatusBytes();
-
- /**
- * <code>optional string checksum = 13;</code>
- */
- boolean hasChecksum();
- /**
- * <code>optional string checksum = 13;</code>
- */
- java.lang.String getChecksum();
- /**
- * <code>optional string checksum = 13;</code>
- */
- com.google.protobuf.ByteString
- getChecksumBytes();
-
- /**
- * <code>optional bool manual_severity = 14;</code>
- */
- boolean hasManualSeverity();
- /**
- * <code>optional bool manual_severity = 14;</code>
- */
- boolean getManualSeverity();
-
- /**
- * <code>optional string reporter = 15;</code>
- */
- boolean hasReporter();
- /**
- * <code>optional string reporter = 15;</code>
- */
- java.lang.String getReporter();
- /**
- * <code>optional string reporter = 15;</code>
- */
- com.google.protobuf.ByteString
- getReporterBytes();
-
- /**
- * <code>optional string assignee = 16;</code>
- */
- boolean hasAssignee();
- /**
- * <code>optional string assignee = 16;</code>
- */
- java.lang.String getAssignee();
- /**
- * <code>optional string assignee = 16;</code>
- */
- com.google.protobuf.ByteString
- getAssigneeBytes();
-
- /**
- * <code>optional string action_plan_key = 17;</code>
- */
- boolean hasActionPlanKey();
- /**
- * <code>optional string action_plan_key = 17;</code>
- */
- java.lang.String getActionPlanKey();
- /**
- * <code>optional string action_plan_key = 17;</code>
- */
- com.google.protobuf.ByteString
- getActionPlanKeyBytes();
-
- /**
- * <code>optional string attributes = 18;</code>
+ * <code>optional string attributes = 8;</code>
*/
boolean hasAttributes();
/**
- * <code>optional string attributes = 18;</code>
+ * <code>optional string attributes = 8;</code>
*/
java.lang.String getAttributes();
/**
- * <code>optional string attributes = 18;</code>
+ * <code>optional string attributes = 8;</code>
*/
com.google.protobuf.ByteString
getAttributesBytes();
/**
- * <code>optional string author_login = 19;</code>
- */
- boolean hasAuthorLogin();
- /**
- * <code>optional string author_login = 19;</code>
- */
- java.lang.String getAuthorLogin();
- /**
- * <code>optional string author_login = 19;</code>
- */
- com.google.protobuf.ByteString
- getAuthorLoginBytes();
-
- /**
- * <code>optional int64 creation_date = 20;</code>
- */
- boolean hasCreationDate();
- /**
- * <code>optional int64 creation_date = 20;</code>
- */
- long getCreationDate();
-
- /**
- * <code>optional int64 close_date = 21;</code>
- */
- boolean hasCloseDate();
- /**
- * <code>optional int64 close_date = 21;</code>
- */
- long getCloseDate();
-
- /**
- * <code>optional int64 update_date = 22;</code>
- */
- boolean hasUpdateDate();
- /**
- * <code>optional int64 update_date = 22;</code>
- */
- long getUpdateDate();
-
- /**
- * <code>optional int64 selected_at = 23;</code>
- */
- boolean hasSelectedAt();
- /**
- * <code>optional int64 selected_at = 23;</code>
- */
- long getSelectedAt();
-
- /**
- * <code>optional string diff_fields = 24;</code>
- */
- boolean hasDiffFields();
- /**
- * <code>optional string diff_fields = 24;</code>
- */
- java.lang.String getDiffFields();
- /**
- * <code>optional string diff_fields = 24;</code>
- */
- com.google.protobuf.ByteString
- getDiffFieldsBytes();
-
- /**
- * <code>optional bool is_changed = 25;</code>
- */
- boolean hasIsChanged();
- /**
- * <code>optional bool is_changed = 25;</code>
- */
- boolean getIsChanged();
-
- /**
- * <code>optional bool must_send_notification = 26;</code>
+ * <code>optional int64 debt_in_minutes = 9;</code>
+ *
+ * <pre>
+ * TODO should it be moved to compute engine?
+ * </pre>
*/
- boolean hasMustSendNotification();
+ boolean hasDebtInMinutes();
/**
- * <code>optional bool must_send_notification = 26;</code>
+ * <code>optional int64 debt_in_minutes = 9;</code>
+ *
+ * <pre>
+ * TODO should it be moved to compute engine?
+ * </pre>
*/
- boolean getMustSendNotification();
+ long getDebtInMinutes();
}
/**
* Protobuf type {@code Issue}
effortToFix_ = input.readDouble();
break;
}
- case 64: {
+ case 66: {
+ com.google.protobuf.ByteString bs = input.readBytes();
bitField0_ |= 0x00000040;
- isNew_ = input.readBool();
+ attributes_ = bs;
break;
}
- case 74: {
- com.google.protobuf.ByteString bs = input.readBytes();
+ case 72: {
bitField0_ |= 0x00000080;
- uuid_ = bs;
- break;
- }
- case 80: {
- bitField0_ |= 0x00000100;
debtInMinutes_ = input.readInt64();
break;
}
- case 90: {
- com.google.protobuf.ByteString bs = input.readBytes();
- bitField0_ |= 0x00000200;
- resolution_ = bs;
- break;
- }
- case 98: {
- com.google.protobuf.ByteString bs = input.readBytes();
- bitField0_ |= 0x00000400;
- status_ = bs;
- break;
- }
- case 106: {
- com.google.protobuf.ByteString bs = input.readBytes();
- bitField0_ |= 0x00000800;
- checksum_ = bs;
- break;
- }
- case 112: {
- bitField0_ |= 0x00001000;
- manualSeverity_ = input.readBool();
- break;
- }
- case 122: {
- com.google.protobuf.ByteString bs = input.readBytes();
- bitField0_ |= 0x00002000;
- reporter_ = bs;
- break;
- }
- case 130: {
- com.google.protobuf.ByteString bs = input.readBytes();
- bitField0_ |= 0x00004000;
- assignee_ = bs;
- break;
- }
- case 138: {
- com.google.protobuf.ByteString bs = input.readBytes();
- bitField0_ |= 0x00008000;
- actionPlanKey_ = bs;
- break;
- }
- case 146: {
- com.google.protobuf.ByteString bs = input.readBytes();
- bitField0_ |= 0x00010000;
- attributes_ = bs;
- break;
- }
- case 154: {
- com.google.protobuf.ByteString bs = input.readBytes();
- bitField0_ |= 0x00020000;
- authorLogin_ = bs;
- break;
- }
- case 160: {
- bitField0_ |= 0x00040000;
- creationDate_ = input.readInt64();
- break;
- }
- case 168: {
- bitField0_ |= 0x00080000;
- closeDate_ = input.readInt64();
- break;
- }
- case 176: {
- bitField0_ |= 0x00100000;
- updateDate_ = input.readInt64();
- break;
- }
- case 184: {
- bitField0_ |= 0x00200000;
- selectedAt_ = input.readInt64();
- break;
- }
- case 194: {
- com.google.protobuf.ByteString bs = input.readBytes();
- bitField0_ |= 0x00400000;
- diffFields_ = bs;
- break;
- }
- case 200: {
- bitField0_ |= 0x00800000;
- isChanged_ = input.readBool();
- break;
- }
- case 208: {
- bitField0_ |= 0x01000000;
- mustSendNotification_ = input.readBool();
- break;
- }
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
private double effortToFix_;
/**
* <code>optional double effort_to_fix = 7;</code>
- *
- * <pre>
- * temporary fields during development of computation stack
- * </pre>
*/
public boolean hasEffortToFix() {
return ((bitField0_ & 0x00000020) == 0x00000020);
}
/**
* <code>optional double effort_to_fix = 7;</code>
- *
- * <pre>
- * temporary fields during development of computation stack
- * </pre>
*/
public double getEffortToFix() {
return effortToFix_;
}
- public static final int IS_NEW_FIELD_NUMBER = 8;
- private boolean isNew_;
+ public static final int ATTRIBUTES_FIELD_NUMBER = 8;
+ private java.lang.Object attributes_;
/**
- * <code>optional bool is_new = 8;</code>
+ * <code>optional string attributes = 8;</code>
*/
- public boolean hasIsNew() {
+ public boolean hasAttributes() {
return ((bitField0_ & 0x00000040) == 0x00000040);
}
/**
- * <code>optional bool is_new = 8;</code>
- */
- public boolean getIsNew() {
- return isNew_;
- }
-
- public static final int UUID_FIELD_NUMBER = 9;
- private java.lang.Object uuid_;
- /**
- * <code>optional string uuid = 9;</code>
- */
- public boolean hasUuid() {
- return ((bitField0_ & 0x00000080) == 0x00000080);
- }
- /**
- * <code>optional string uuid = 9;</code>
+ * <code>optional string attributes = 8;</code>
*/
- public java.lang.String getUuid() {
- java.lang.Object ref = uuid_;
+ public java.lang.String getAttributes() {
+ java.lang.Object ref = attributes_;
if (ref instanceof java.lang.String) {
return (java.lang.String) ref;
} else {
(com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
if (bs.isValidUtf8()) {
- uuid_ = s;
+ attributes_ = s;
}
return s;
}
}
/**
- * <code>optional string uuid = 9;</code>
+ * <code>optional string attributes = 8;</code>
*/
public com.google.protobuf.ByteString
- getUuidBytes() {
- java.lang.Object ref = uuid_;
+ getAttributesBytes() {
+ java.lang.Object ref = attributes_;
if (ref instanceof java.lang.String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8(
(java.lang.String) ref);
- uuid_ = b;
+ attributes_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
- public static final int DEBT_IN_MINUTES_FIELD_NUMBER = 10;
+ public static final int DEBT_IN_MINUTES_FIELD_NUMBER = 9;
private long debtInMinutes_;
/**
- * <code>optional int64 debt_in_minutes = 10;</code>
+ * <code>optional int64 debt_in_minutes = 9;</code>
+ *
+ * <pre>
+ * TODO should it be moved to compute engine?
+ * </pre>
*/
public boolean hasDebtInMinutes() {
- return ((bitField0_ & 0x00000100) == 0x00000100);
+ return ((bitField0_ & 0x00000080) == 0x00000080);
}
/**
- * <code>optional int64 debt_in_minutes = 10;</code>
+ * <code>optional int64 debt_in_minutes = 9;</code>
+ *
+ * <pre>
+ * TODO should it be moved to compute engine?
+ * </pre>
*/
public long getDebtInMinutes() {
return debtInMinutes_;
}
- public static final int RESOLUTION_FIELD_NUMBER = 11;
- private java.lang.Object resolution_;
- /**
- * <code>optional string resolution = 11;</code>
- */
- public boolean hasResolution() {
- return ((bitField0_ & 0x00000200) == 0x00000200);
- }
- /**
- * <code>optional string resolution = 11;</code>
- */
- public java.lang.String getResolution() {
- java.lang.Object ref = resolution_;
- if (ref instanceof java.lang.String) {
- return (java.lang.String) ref;
- } else {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- resolution_ = s;
- }
- return s;
- }
- }
- /**
- * <code>optional string resolution = 11;</code>
- */
- public com.google.protobuf.ByteString
- getResolutionBytes() {
- java.lang.Object ref = resolution_;
- if (ref instanceof java.lang.String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- resolution_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
+ private void initFields() {
+ ruleRepository_ = "";
+ ruleKey_ = "";
+ line_ = 0;
+ msg_ = "";
+ severity_ = org.sonar.batch.protocol.Constants.Severity.INFO;
+ tag_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+ effortToFix_ = 0D;
+ attributes_ = "";
+ debtInMinutes_ = 0L;
}
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized == 1) return true;
+ if (isInitialized == 0) return false;
- public static final int STATUS_FIELD_NUMBER = 12;
- private java.lang.Object status_;
- /**
- * <code>optional string status = 12;</code>
- */
- public boolean hasStatus() {
- return ((bitField0_ & 0x00000400) == 0x00000400);
+ memoizedIsInitialized = 1;
+ return true;
}
- /**
- * <code>optional string status = 12;</code>
- */
- public java.lang.String getStatus() {
- java.lang.Object ref = status_;
- if (ref instanceof java.lang.String) {
- return (java.lang.String) ref;
- } else {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- status_ = s;
- }
- return s;
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(1, getRuleRepositoryBytes());
}
- }
- /**
- * <code>optional string status = 12;</code>
- */
- public com.google.protobuf.ByteString
- getStatusBytes() {
- java.lang.Object ref = status_;
- if (ref instanceof java.lang.String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- status_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ output.writeBytes(2, getRuleKeyBytes());
}
- }
-
- public static final int CHECKSUM_FIELD_NUMBER = 13;
- private java.lang.Object checksum_;
- /**
- * <code>optional string checksum = 13;</code>
- */
- public boolean hasChecksum() {
- return ((bitField0_ & 0x00000800) == 0x00000800);
- }
- /**
- * <code>optional string checksum = 13;</code>
- */
- public java.lang.String getChecksum() {
- java.lang.Object ref = checksum_;
- if (ref instanceof java.lang.String) {
- return (java.lang.String) ref;
- } else {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- checksum_ = s;
- }
- return s;
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ output.writeInt32(3, line_);
}
- }
- /**
- * <code>optional string checksum = 13;</code>
- */
- public com.google.protobuf.ByteString
- getChecksumBytes() {
- java.lang.Object ref = checksum_;
- if (ref instanceof java.lang.String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- checksum_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ output.writeBytes(4, getMsgBytes());
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ output.writeEnum(5, severity_.getNumber());
+ }
+ for (int i = 0; i < tag_.size(); i++) {
+ output.writeBytes(6, tag_.getByteString(i));
+ }
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ output.writeDouble(7, effortToFix_);
}
+ if (((bitField0_ & 0x00000040) == 0x00000040)) {
+ output.writeBytes(8, getAttributesBytes());
+ }
+ if (((bitField0_ & 0x00000080) == 0x00000080)) {
+ output.writeInt64(9, debtInMinutes_);
+ }
+ getUnknownFields().writeTo(output);
}
- public static final int MANUAL_SEVERITY_FIELD_NUMBER = 14;
- private boolean manualSeverity_;
- /**
- * <code>optional bool manual_severity = 14;</code>
- */
- public boolean hasManualSeverity() {
- return ((bitField0_ & 0x00001000) == 0x00001000);
- }
- /**
- * <code>optional bool manual_severity = 14;</code>
- */
- public boolean getManualSeverity() {
- return manualSeverity_;
- }
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
- public static final int REPORTER_FIELD_NUMBER = 15;
- private java.lang.Object reporter_;
- /**
- * <code>optional string reporter = 15;</code>
- */
- public boolean hasReporter() {
- return ((bitField0_ & 0x00002000) == 0x00002000);
- }
- /**
- * <code>optional string reporter = 15;</code>
- */
- public java.lang.String getReporter() {
- java.lang.Object ref = reporter_;
- if (ref instanceof java.lang.String) {
- return (java.lang.String) ref;
- } else {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- reporter_ = s;
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(1, getRuleRepositoryBytes());
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(2, getRuleKeyBytes());
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeInt32Size(3, line_);
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(4, getMsgBytes());
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeEnumSize(5, severity_.getNumber());
+ }
+ {
+ int dataSize = 0;
+ for (int i = 0; i < tag_.size(); i++) {
+ dataSize += com.google.protobuf.CodedOutputStream
+ .computeBytesSizeNoTag(tag_.getByteString(i));
}
- return s;
+ size += dataSize;
+ size += 1 * getTagList().size();
}
- }
- /**
- * <code>optional string reporter = 15;</code>
- */
- public com.google.protobuf.ByteString
- getReporterBytes() {
- java.lang.Object ref = reporter_;
- if (ref instanceof java.lang.String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- reporter_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeDoubleSize(7, effortToFix_);
}
+ if (((bitField0_ & 0x00000040) == 0x00000040)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(8, getAttributesBytes());
+ }
+ if (((bitField0_ & 0x00000080) == 0x00000080)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeInt64Size(9, debtInMinutes_);
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
}
- public static final int ASSIGNEE_FIELD_NUMBER = 16;
- private java.lang.Object assignee_;
- /**
- * <code>optional string assignee = 16;</code>
- */
- public boolean hasAssignee() {
- return ((bitField0_ & 0x00004000) == 0x00004000);
- }
- /**
- * <code>optional string assignee = 16;</code>
- */
- public java.lang.String getAssignee() {
- java.lang.Object ref = assignee_;
- if (ref instanceof java.lang.String) {
- return (java.lang.String) ref;
- } else {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- assignee_ = s;
- }
- return s;
- }
- }
- /**
- * <code>optional string assignee = 16;</code>
- */
- public com.google.protobuf.ByteString
- getAssigneeBytes() {
- java.lang.Object ref = assignee_;
- if (ref instanceof java.lang.String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- assignee_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
}
- public static final int ACTION_PLAN_KEY_FIELD_NUMBER = 17;
- private java.lang.Object actionPlanKey_;
- /**
- * <code>optional string action_plan_key = 17;</code>
- */
- public boolean hasActionPlanKey() {
- return ((bitField0_ & 0x00008000) == 0x00008000);
- }
- /**
- * <code>optional string action_plan_key = 17;</code>
- */
- public java.lang.String getActionPlanKey() {
- java.lang.Object ref = actionPlanKey_;
- if (ref instanceof java.lang.String) {
- return (java.lang.String) ref;
- } else {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- actionPlanKey_ = s;
- }
- return s;
- }
+ public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
}
- /**
- * <code>optional string action_plan_key = 17;</code>
- */
- public com.google.protobuf.ByteString
- getActionPlanKeyBytes() {
- java.lang.Object ref = actionPlanKey_;
- if (ref instanceof java.lang.String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- actionPlanKey_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
+ public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
}
-
- public static final int ATTRIBUTES_FIELD_NUMBER = 18;
- private java.lang.Object attributes_;
- /**
- * <code>optional string attributes = 18;</code>
- */
- public boolean hasAttributes() {
- return ((bitField0_ & 0x00010000) == 0x00010000);
+ public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
}
- /**
- * <code>optional string attributes = 18;</code>
- */
- public java.lang.String getAttributes() {
- java.lang.Object ref = attributes_;
- if (ref instanceof java.lang.String) {
- return (java.lang.String) ref;
- } else {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- attributes_ = s;
- }
- return s;
- }
+ public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
}
- /**
- * <code>optional string attributes = 18;</code>
- */
- public com.google.protobuf.ByteString
- getAttributesBytes() {
- java.lang.Object ref = attributes_;
- if (ref instanceof java.lang.String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- attributes_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
+ public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
}
-
- public static final int AUTHOR_LOGIN_FIELD_NUMBER = 19;
- private java.lang.Object authorLogin_;
- /**
- * <code>optional string author_login = 19;</code>
- */
- public boolean hasAuthorLogin() {
- return ((bitField0_ & 0x00020000) == 0x00020000);
+ public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
}
- /**
- * <code>optional string author_login = 19;</code>
- */
- public java.lang.String getAuthorLogin() {
- java.lang.Object ref = authorLogin_;
- if (ref instanceof java.lang.String) {
- return (java.lang.String) ref;
- } else {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- authorLogin_ = s;
- }
- return s;
- }
+ public static org.sonar.batch.protocol.output.BatchReport.Issue parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
}
- /**
- * <code>optional string author_login = 19;</code>
- */
- public com.google.protobuf.ByteString
- getAuthorLoginBytes() {
- java.lang.Object ref = authorLogin_;
- if (ref instanceof java.lang.String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- authorLogin_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
+ public static org.sonar.batch.protocol.output.BatchReport.Issue parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
}
-
- public static final int CREATION_DATE_FIELD_NUMBER = 20;
- private long creationDate_;
- /**
- * <code>optional int64 creation_date = 20;</code>
- */
- public boolean hasCreationDate() {
- return ((bitField0_ & 0x00040000) == 0x00040000);
+ public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
}
- /**
- * <code>optional int64 creation_date = 20;</code>
- */
- public long getCreationDate() {
- return creationDate_;
+ public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
}
- public static final int CLOSE_DATE_FIELD_NUMBER = 21;
- private long closeDate_;
- /**
- * <code>optional int64 close_date = 21;</code>
- */
- public boolean hasCloseDate() {
- return ((bitField0_ & 0x00080000) == 0x00080000);
- }
- /**
- * <code>optional int64 close_date = 21;</code>
- */
- public long getCloseDate() {
- return closeDate_;
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(org.sonar.batch.protocol.output.BatchReport.Issue prototype) {
+ return newBuilder().mergeFrom(prototype);
}
+ public Builder toBuilder() { return newBuilder(this); }
- public static final int UPDATE_DATE_FIELD_NUMBER = 22;
- private long updateDate_;
- /**
- * <code>optional int64 update_date = 22;</code>
- */
- public boolean hasUpdateDate() {
- return ((bitField0_ & 0x00100000) == 0x00100000);
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
}
/**
- * <code>optional int64 update_date = 22;</code>
+ * Protobuf type {@code Issue}
*/
- public long getUpdateDate() {
- return updateDate_;
- }
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+ // @@protoc_insertion_point(builder_implements:Issue)
+ org.sonar.batch.protocol.output.BatchReport.IssueOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return org.sonar.batch.protocol.output.BatchReport.internal_static_Issue_descriptor;
+ }
- public static final int SELECTED_AT_FIELD_NUMBER = 23;
- private long selectedAt_;
- /**
- * <code>optional int64 selected_at = 23;</code>
- */
- public boolean hasSelectedAt() {
- return ((bitField0_ & 0x00200000) == 0x00200000);
- }
- /**
- * <code>optional int64 selected_at = 23;</code>
- */
- public long getSelectedAt() {
- return selectedAt_;
- }
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return org.sonar.batch.protocol.output.BatchReport.internal_static_Issue_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ org.sonar.batch.protocol.output.BatchReport.Issue.class, org.sonar.batch.protocol.output.BatchReport.Issue.Builder.class);
+ }
- public static final int DIFF_FIELDS_FIELD_NUMBER = 24;
- private java.lang.Object diffFields_;
- /**
- * <code>optional string diff_fields = 24;</code>
- */
- public boolean hasDiffFields() {
- return ((bitField0_ & 0x00400000) == 0x00400000);
- }
- /**
- * <code>optional string diff_fields = 24;</code>
- */
- public java.lang.String getDiffFields() {
- java.lang.Object ref = diffFields_;
- if (ref instanceof java.lang.String) {
- return (java.lang.String) ref;
- } else {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- diffFields_ = s;
+ // Construct using org.sonar.batch.protocol.output.BatchReport.Issue.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
}
- return s;
}
- }
- /**
- * <code>optional string diff_fields = 24;</code>
- */
- public com.google.protobuf.ByteString
- getDiffFieldsBytes() {
- java.lang.Object ref = diffFields_;
- if (ref instanceof java.lang.String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- diffFields_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
+ private static Builder create() {
+ return new Builder();
}
- }
-
- public static final int IS_CHANGED_FIELD_NUMBER = 25;
- private boolean isChanged_;
- /**
- * <code>optional bool is_changed = 25;</code>
- */
- public boolean hasIsChanged() {
- return ((bitField0_ & 0x00800000) == 0x00800000);
- }
- /**
- * <code>optional bool is_changed = 25;</code>
- */
- public boolean getIsChanged() {
- return isChanged_;
- }
-
- public static final int MUST_SEND_NOTIFICATION_FIELD_NUMBER = 26;
- private boolean mustSendNotification_;
- /**
- * <code>optional bool must_send_notification = 26;</code>
- */
- public boolean hasMustSendNotification() {
- return ((bitField0_ & 0x01000000) == 0x01000000);
- }
- /**
- * <code>optional bool must_send_notification = 26;</code>
- */
- public boolean getMustSendNotification() {
- return mustSendNotification_;
- }
- private void initFields() {
- ruleRepository_ = "";
- ruleKey_ = "";
- line_ = 0;
- msg_ = "";
- severity_ = org.sonar.batch.protocol.Constants.Severity.INFO;
- tag_ = com.google.protobuf.LazyStringArrayList.EMPTY;
- effortToFix_ = 0D;
- isNew_ = false;
- uuid_ = "";
- debtInMinutes_ = 0L;
- resolution_ = "";
- status_ = "";
- checksum_ = "";
- manualSeverity_ = false;
- reporter_ = "";
- assignee_ = "";
- actionPlanKey_ = "";
- attributes_ = "";
- authorLogin_ = "";
- creationDate_ = 0L;
- closeDate_ = 0L;
- updateDate_ = 0L;
- selectedAt_ = 0L;
- diffFields_ = "";
- isChanged_ = false;
- mustSendNotification_ = false;
- }
- private byte memoizedIsInitialized = -1;
- public final boolean isInitialized() {
- byte isInitialized = memoizedIsInitialized;
- if (isInitialized == 1) return true;
- if (isInitialized == 0) return false;
-
- memoizedIsInitialized = 1;
- return true;
- }
-
- public void writeTo(com.google.protobuf.CodedOutputStream output)
- throws java.io.IOException {
- getSerializedSize();
- if (((bitField0_ & 0x00000001) == 0x00000001)) {
- output.writeBytes(1, getRuleRepositoryBytes());
- }
- if (((bitField0_ & 0x00000002) == 0x00000002)) {
- output.writeBytes(2, getRuleKeyBytes());
- }
- if (((bitField0_ & 0x00000004) == 0x00000004)) {
- output.writeInt32(3, line_);
- }
- if (((bitField0_ & 0x00000008) == 0x00000008)) {
- output.writeBytes(4, getMsgBytes());
- }
- if (((bitField0_ & 0x00000010) == 0x00000010)) {
- output.writeEnum(5, severity_.getNumber());
- }
- for (int i = 0; i < tag_.size(); i++) {
- output.writeBytes(6, tag_.getByteString(i));
- }
- if (((bitField0_ & 0x00000020) == 0x00000020)) {
- output.writeDouble(7, effortToFix_);
- }
- if (((bitField0_ & 0x00000040) == 0x00000040)) {
- output.writeBool(8, isNew_);
- }
- if (((bitField0_ & 0x00000080) == 0x00000080)) {
- output.writeBytes(9, getUuidBytes());
- }
- if (((bitField0_ & 0x00000100) == 0x00000100)) {
- output.writeInt64(10, debtInMinutes_);
- }
- if (((bitField0_ & 0x00000200) == 0x00000200)) {
- output.writeBytes(11, getResolutionBytes());
- }
- if (((bitField0_ & 0x00000400) == 0x00000400)) {
- output.writeBytes(12, getStatusBytes());
- }
- if (((bitField0_ & 0x00000800) == 0x00000800)) {
- output.writeBytes(13, getChecksumBytes());
- }
- if (((bitField0_ & 0x00001000) == 0x00001000)) {
- output.writeBool(14, manualSeverity_);
- }
- if (((bitField0_ & 0x00002000) == 0x00002000)) {
- output.writeBytes(15, getReporterBytes());
- }
- if (((bitField0_ & 0x00004000) == 0x00004000)) {
- output.writeBytes(16, getAssigneeBytes());
- }
- if (((bitField0_ & 0x00008000) == 0x00008000)) {
- output.writeBytes(17, getActionPlanKeyBytes());
- }
- if (((bitField0_ & 0x00010000) == 0x00010000)) {
- output.writeBytes(18, getAttributesBytes());
- }
- if (((bitField0_ & 0x00020000) == 0x00020000)) {
- output.writeBytes(19, getAuthorLoginBytes());
- }
- if (((bitField0_ & 0x00040000) == 0x00040000)) {
- output.writeInt64(20, creationDate_);
- }
- if (((bitField0_ & 0x00080000) == 0x00080000)) {
- output.writeInt64(21, closeDate_);
- }
- if (((bitField0_ & 0x00100000) == 0x00100000)) {
- output.writeInt64(22, updateDate_);
- }
- if (((bitField0_ & 0x00200000) == 0x00200000)) {
- output.writeInt64(23, selectedAt_);
- }
- if (((bitField0_ & 0x00400000) == 0x00400000)) {
- output.writeBytes(24, getDiffFieldsBytes());
- }
- if (((bitField0_ & 0x00800000) == 0x00800000)) {
- output.writeBool(25, isChanged_);
- }
- if (((bitField0_ & 0x01000000) == 0x01000000)) {
- output.writeBool(26, mustSendNotification_);
- }
- getUnknownFields().writeTo(output);
- }
-
- private int memoizedSerializedSize = -1;
- public int getSerializedSize() {
- int size = memoizedSerializedSize;
- if (size != -1) return size;
-
- size = 0;
- if (((bitField0_ & 0x00000001) == 0x00000001)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(1, getRuleRepositoryBytes());
- }
- if (((bitField0_ & 0x00000002) == 0x00000002)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(2, getRuleKeyBytes());
- }
- if (((bitField0_ & 0x00000004) == 0x00000004)) {
- size += com.google.protobuf.CodedOutputStream
- .computeInt32Size(3, line_);
- }
- if (((bitField0_ & 0x00000008) == 0x00000008)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(4, getMsgBytes());
- }
- if (((bitField0_ & 0x00000010) == 0x00000010)) {
- size += com.google.protobuf.CodedOutputStream
- .computeEnumSize(5, severity_.getNumber());
- }
- {
- int dataSize = 0;
- for (int i = 0; i < tag_.size(); i++) {
- dataSize += com.google.protobuf.CodedOutputStream
- .computeBytesSizeNoTag(tag_.getByteString(i));
- }
- size += dataSize;
- size += 1 * getTagList().size();
- }
- if (((bitField0_ & 0x00000020) == 0x00000020)) {
- size += com.google.protobuf.CodedOutputStream
- .computeDoubleSize(7, effortToFix_);
- }
- if (((bitField0_ & 0x00000040) == 0x00000040)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBoolSize(8, isNew_);
- }
- if (((bitField0_ & 0x00000080) == 0x00000080)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(9, getUuidBytes());
- }
- if (((bitField0_ & 0x00000100) == 0x00000100)) {
- size += com.google.protobuf.CodedOutputStream
- .computeInt64Size(10, debtInMinutes_);
- }
- if (((bitField0_ & 0x00000200) == 0x00000200)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(11, getResolutionBytes());
- }
- if (((bitField0_ & 0x00000400) == 0x00000400)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(12, getStatusBytes());
- }
- if (((bitField0_ & 0x00000800) == 0x00000800)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(13, getChecksumBytes());
- }
- if (((bitField0_ & 0x00001000) == 0x00001000)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBoolSize(14, manualSeverity_);
- }
- if (((bitField0_ & 0x00002000) == 0x00002000)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(15, getReporterBytes());
- }
- if (((bitField0_ & 0x00004000) == 0x00004000)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(16, getAssigneeBytes());
- }
- if (((bitField0_ & 0x00008000) == 0x00008000)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(17, getActionPlanKeyBytes());
- }
- if (((bitField0_ & 0x00010000) == 0x00010000)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(18, getAttributesBytes());
- }
- if (((bitField0_ & 0x00020000) == 0x00020000)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(19, getAuthorLoginBytes());
- }
- if (((bitField0_ & 0x00040000) == 0x00040000)) {
- size += com.google.protobuf.CodedOutputStream
- .computeInt64Size(20, creationDate_);
- }
- if (((bitField0_ & 0x00080000) == 0x00080000)) {
- size += com.google.protobuf.CodedOutputStream
- .computeInt64Size(21, closeDate_);
- }
- if (((bitField0_ & 0x00100000) == 0x00100000)) {
- size += com.google.protobuf.CodedOutputStream
- .computeInt64Size(22, updateDate_);
- }
- if (((bitField0_ & 0x00200000) == 0x00200000)) {
- size += com.google.protobuf.CodedOutputStream
- .computeInt64Size(23, selectedAt_);
- }
- if (((bitField0_ & 0x00400000) == 0x00400000)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(24, getDiffFieldsBytes());
- }
- if (((bitField0_ & 0x00800000) == 0x00800000)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBoolSize(25, isChanged_);
- }
- if (((bitField0_ & 0x01000000) == 0x01000000)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBoolSize(26, mustSendNotification_);
- }
- size += getUnknownFields().getSerializedSize();
- memoizedSerializedSize = size;
- return size;
- }
-
- private static final long serialVersionUID = 0L;
- @java.lang.Override
- protected java.lang.Object writeReplace()
- throws java.io.ObjectStreamException {
- return super.writeReplace();
- }
-
- public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(
- com.google.protobuf.ByteString data)
- throws com.google.protobuf.InvalidProtocolBufferException {
- return PARSER.parseFrom(data);
- }
- public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(
- com.google.protobuf.ByteString data,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws com.google.protobuf.InvalidProtocolBufferException {
- return PARSER.parseFrom(data, extensionRegistry);
- }
- public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(byte[] data)
- throws com.google.protobuf.InvalidProtocolBufferException {
- return PARSER.parseFrom(data);
- }
- public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(
- byte[] data,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws com.google.protobuf.InvalidProtocolBufferException {
- return PARSER.parseFrom(data, extensionRegistry);
- }
- public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(java.io.InputStream input)
- throws java.io.IOException {
- return PARSER.parseFrom(input);
- }
- public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(
- java.io.InputStream input,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws java.io.IOException {
- return PARSER.parseFrom(input, extensionRegistry);
- }
- public static org.sonar.batch.protocol.output.BatchReport.Issue parseDelimitedFrom(java.io.InputStream input)
- throws java.io.IOException {
- return PARSER.parseDelimitedFrom(input);
- }
- public static org.sonar.batch.protocol.output.BatchReport.Issue parseDelimitedFrom(
- java.io.InputStream input,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws java.io.IOException {
- return PARSER.parseDelimitedFrom(input, extensionRegistry);
- }
- public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(
- com.google.protobuf.CodedInputStream input)
- throws java.io.IOException {
- return PARSER.parseFrom(input);
- }
- public static org.sonar.batch.protocol.output.BatchReport.Issue parseFrom(
- com.google.protobuf.CodedInputStream input,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws java.io.IOException {
- return PARSER.parseFrom(input, extensionRegistry);
- }
-
- public static Builder newBuilder() { return Builder.create(); }
- public Builder newBuilderForType() { return newBuilder(); }
- public static Builder newBuilder(org.sonar.batch.protocol.output.BatchReport.Issue prototype) {
- return newBuilder().mergeFrom(prototype);
- }
- public Builder toBuilder() { return newBuilder(this); }
-
- @java.lang.Override
- protected Builder newBuilderForType(
- com.google.protobuf.GeneratedMessage.BuilderParent parent) {
- Builder builder = new Builder(parent);
- return builder;
- }
- /**
- * Protobuf type {@code Issue}
- */
- public static final class Builder extends
- com.google.protobuf.GeneratedMessage.Builder<Builder> implements
- // @@protoc_insertion_point(builder_implements:Issue)
- org.sonar.batch.protocol.output.BatchReport.IssueOrBuilder {
- public static final com.google.protobuf.Descriptors.Descriptor
- getDescriptor() {
- return org.sonar.batch.protocol.output.BatchReport.internal_static_Issue_descriptor;
- }
-
- protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
- internalGetFieldAccessorTable() {
- return org.sonar.batch.protocol.output.BatchReport.internal_static_Issue_fieldAccessorTable
- .ensureFieldAccessorsInitialized(
- org.sonar.batch.protocol.output.BatchReport.Issue.class, org.sonar.batch.protocol.output.BatchReport.Issue.Builder.class);
- }
-
- // Construct using org.sonar.batch.protocol.output.BatchReport.Issue.newBuilder()
- private Builder() {
- maybeForceBuilderInitialization();
- }
-
- private Builder(
- com.google.protobuf.GeneratedMessage.BuilderParent parent) {
- super(parent);
- maybeForceBuilderInitialization();
- }
- private void maybeForceBuilderInitialization() {
- if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
- }
- }
- private static Builder create() {
- return new Builder();
- }
-
- public Builder clear() {
- super.clear();
- ruleRepository_ = "";
- bitField0_ = (bitField0_ & ~0x00000001);
- ruleKey_ = "";
- bitField0_ = (bitField0_ & ~0x00000002);
- line_ = 0;
- bitField0_ = (bitField0_ & ~0x00000004);
- msg_ = "";
- bitField0_ = (bitField0_ & ~0x00000008);
- severity_ = org.sonar.batch.protocol.Constants.Severity.INFO;
- bitField0_ = (bitField0_ & ~0x00000010);
- tag_ = com.google.protobuf.LazyStringArrayList.EMPTY;
- bitField0_ = (bitField0_ & ~0x00000020);
- effortToFix_ = 0D;
- bitField0_ = (bitField0_ & ~0x00000040);
- isNew_ = false;
- bitField0_ = (bitField0_ & ~0x00000080);
- uuid_ = "";
- bitField0_ = (bitField0_ & ~0x00000100);
- debtInMinutes_ = 0L;
- bitField0_ = (bitField0_ & ~0x00000200);
- resolution_ = "";
- bitField0_ = (bitField0_ & ~0x00000400);
- status_ = "";
- bitField0_ = (bitField0_ & ~0x00000800);
- checksum_ = "";
- bitField0_ = (bitField0_ & ~0x00001000);
- manualSeverity_ = false;
- bitField0_ = (bitField0_ & ~0x00002000);
- reporter_ = "";
- bitField0_ = (bitField0_ & ~0x00004000);
- assignee_ = "";
- bitField0_ = (bitField0_ & ~0x00008000);
- actionPlanKey_ = "";
- bitField0_ = (bitField0_ & ~0x00010000);
- attributes_ = "";
- bitField0_ = (bitField0_ & ~0x00020000);
- authorLogin_ = "";
- bitField0_ = (bitField0_ & ~0x00040000);
- creationDate_ = 0L;
- bitField0_ = (bitField0_ & ~0x00080000);
- closeDate_ = 0L;
- bitField0_ = (bitField0_ & ~0x00100000);
- updateDate_ = 0L;
- bitField0_ = (bitField0_ & ~0x00200000);
- selectedAt_ = 0L;
- bitField0_ = (bitField0_ & ~0x00400000);
- diffFields_ = "";
- bitField0_ = (bitField0_ & ~0x00800000);
- isChanged_ = false;
- bitField0_ = (bitField0_ & ~0x01000000);
- mustSendNotification_ = false;
- bitField0_ = (bitField0_ & ~0x02000000);
- return this;
- }
-
- public Builder clone() {
- return create().mergeFrom(buildPartial());
- }
-
- public com.google.protobuf.Descriptors.Descriptor
- getDescriptorForType() {
- return org.sonar.batch.protocol.output.BatchReport.internal_static_Issue_descriptor;
- }
-
- public org.sonar.batch.protocol.output.BatchReport.Issue getDefaultInstanceForType() {
- return org.sonar.batch.protocol.output.BatchReport.Issue.getDefaultInstance();
- }
-
- public org.sonar.batch.protocol.output.BatchReport.Issue build() {
- org.sonar.batch.protocol.output.BatchReport.Issue result = buildPartial();
- if (!result.isInitialized()) {
- throw newUninitializedMessageException(result);
- }
- return result;
- }
-
- public org.sonar.batch.protocol.output.BatchReport.Issue buildPartial() {
- org.sonar.batch.protocol.output.BatchReport.Issue result = new org.sonar.batch.protocol.output.BatchReport.Issue(this);
- int from_bitField0_ = bitField0_;
- int to_bitField0_ = 0;
- if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
- to_bitField0_ |= 0x00000001;
- }
- result.ruleRepository_ = ruleRepository_;
- if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
- to_bitField0_ |= 0x00000002;
- }
- result.ruleKey_ = ruleKey_;
- if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
- to_bitField0_ |= 0x00000004;
- }
- result.line_ = line_;
- if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
- to_bitField0_ |= 0x00000008;
- }
- result.msg_ = msg_;
- if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
- to_bitField0_ |= 0x00000010;
- }
- result.severity_ = severity_;
- if (((bitField0_ & 0x00000020) == 0x00000020)) {
- tag_ = tag_.getUnmodifiableView();
- bitField0_ = (bitField0_ & ~0x00000020);
- }
- result.tag_ = tag_;
- if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
- to_bitField0_ |= 0x00000020;
- }
- result.effortToFix_ = effortToFix_;
- if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
- to_bitField0_ |= 0x00000040;
- }
- result.isNew_ = isNew_;
- if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
- to_bitField0_ |= 0x00000080;
- }
- result.uuid_ = uuid_;
- if (((from_bitField0_ & 0x00000200) == 0x00000200)) {
- to_bitField0_ |= 0x00000100;
- }
- result.debtInMinutes_ = debtInMinutes_;
- if (((from_bitField0_ & 0x00000400) == 0x00000400)) {
- to_bitField0_ |= 0x00000200;
- }
- result.resolution_ = resolution_;
- if (((from_bitField0_ & 0x00000800) == 0x00000800)) {
- to_bitField0_ |= 0x00000400;
- }
- result.status_ = status_;
- if (((from_bitField0_ & 0x00001000) == 0x00001000)) {
- to_bitField0_ |= 0x00000800;
- }
- result.checksum_ = checksum_;
- if (((from_bitField0_ & 0x00002000) == 0x00002000)) {
- to_bitField0_ |= 0x00001000;
- }
- result.manualSeverity_ = manualSeverity_;
- if (((from_bitField0_ & 0x00004000) == 0x00004000)) {
- to_bitField0_ |= 0x00002000;
- }
- result.reporter_ = reporter_;
- if (((from_bitField0_ & 0x00008000) == 0x00008000)) {
- to_bitField0_ |= 0x00004000;
- }
- result.assignee_ = assignee_;
- if (((from_bitField0_ & 0x00010000) == 0x00010000)) {
- to_bitField0_ |= 0x00008000;
- }
- result.actionPlanKey_ = actionPlanKey_;
- if (((from_bitField0_ & 0x00020000) == 0x00020000)) {
- to_bitField0_ |= 0x00010000;
- }
- result.attributes_ = attributes_;
- if (((from_bitField0_ & 0x00040000) == 0x00040000)) {
- to_bitField0_ |= 0x00020000;
- }
- result.authorLogin_ = authorLogin_;
- if (((from_bitField0_ & 0x00080000) == 0x00080000)) {
- to_bitField0_ |= 0x00040000;
- }
- result.creationDate_ = creationDate_;
- if (((from_bitField0_ & 0x00100000) == 0x00100000)) {
- to_bitField0_ |= 0x00080000;
- }
- result.closeDate_ = closeDate_;
- if (((from_bitField0_ & 0x00200000) == 0x00200000)) {
- to_bitField0_ |= 0x00100000;
- }
- result.updateDate_ = updateDate_;
- if (((from_bitField0_ & 0x00400000) == 0x00400000)) {
- to_bitField0_ |= 0x00200000;
- }
- result.selectedAt_ = selectedAt_;
- if (((from_bitField0_ & 0x00800000) == 0x00800000)) {
- to_bitField0_ |= 0x00400000;
- }
- result.diffFields_ = diffFields_;
- if (((from_bitField0_ & 0x01000000) == 0x01000000)) {
- to_bitField0_ |= 0x00800000;
- }
- result.isChanged_ = isChanged_;
- if (((from_bitField0_ & 0x02000000) == 0x02000000)) {
- to_bitField0_ |= 0x01000000;
- }
- result.mustSendNotification_ = mustSendNotification_;
- result.bitField0_ = to_bitField0_;
- onBuilt();
- return result;
- }
-
- public Builder mergeFrom(com.google.protobuf.Message other) {
- if (other instanceof org.sonar.batch.protocol.output.BatchReport.Issue) {
- return mergeFrom((org.sonar.batch.protocol.output.BatchReport.Issue)other);
- } else {
- super.mergeFrom(other);
- return this;
- }
- }
-
- public Builder mergeFrom(org.sonar.batch.protocol.output.BatchReport.Issue other) {
- if (other == org.sonar.batch.protocol.output.BatchReport.Issue.getDefaultInstance()) return this;
- if (other.hasRuleRepository()) {
- bitField0_ |= 0x00000001;
- ruleRepository_ = other.ruleRepository_;
- onChanged();
- }
- if (other.hasRuleKey()) {
- bitField0_ |= 0x00000002;
- ruleKey_ = other.ruleKey_;
- onChanged();
- }
- if (other.hasLine()) {
- setLine(other.getLine());
- }
- if (other.hasMsg()) {
- bitField0_ |= 0x00000008;
- msg_ = other.msg_;
- onChanged();
- }
- if (other.hasSeverity()) {
- setSeverity(other.getSeverity());
- }
- if (!other.tag_.isEmpty()) {
- if (tag_.isEmpty()) {
- tag_ = other.tag_;
- bitField0_ = (bitField0_ & ~0x00000020);
- } else {
- ensureTagIsMutable();
- tag_.addAll(other.tag_);
- }
- onChanged();
- }
- if (other.hasEffortToFix()) {
- setEffortToFix(other.getEffortToFix());
- }
- if (other.hasIsNew()) {
- setIsNew(other.getIsNew());
- }
- if (other.hasUuid()) {
- bitField0_ |= 0x00000100;
- uuid_ = other.uuid_;
- onChanged();
- }
- if (other.hasDebtInMinutes()) {
- setDebtInMinutes(other.getDebtInMinutes());
- }
- if (other.hasResolution()) {
- bitField0_ |= 0x00000400;
- resolution_ = other.resolution_;
- onChanged();
- }
- if (other.hasStatus()) {
- bitField0_ |= 0x00000800;
- status_ = other.status_;
- onChanged();
- }
- if (other.hasChecksum()) {
- bitField0_ |= 0x00001000;
- checksum_ = other.checksum_;
- onChanged();
- }
- if (other.hasManualSeverity()) {
- setManualSeverity(other.getManualSeverity());
- }
- if (other.hasReporter()) {
- bitField0_ |= 0x00004000;
- reporter_ = other.reporter_;
- onChanged();
- }
- if (other.hasAssignee()) {
- bitField0_ |= 0x00008000;
- assignee_ = other.assignee_;
- onChanged();
- }
- if (other.hasActionPlanKey()) {
- bitField0_ |= 0x00010000;
- actionPlanKey_ = other.actionPlanKey_;
- onChanged();
- }
- if (other.hasAttributes()) {
- bitField0_ |= 0x00020000;
- attributes_ = other.attributes_;
- onChanged();
- }
- if (other.hasAuthorLogin()) {
- bitField0_ |= 0x00040000;
- authorLogin_ = other.authorLogin_;
- onChanged();
- }
- if (other.hasCreationDate()) {
- setCreationDate(other.getCreationDate());
- }
- if (other.hasCloseDate()) {
- setCloseDate(other.getCloseDate());
- }
- if (other.hasUpdateDate()) {
- setUpdateDate(other.getUpdateDate());
- }
- if (other.hasSelectedAt()) {
- setSelectedAt(other.getSelectedAt());
- }
- if (other.hasDiffFields()) {
- bitField0_ |= 0x00800000;
- diffFields_ = other.diffFields_;
- onChanged();
- }
- if (other.hasIsChanged()) {
- setIsChanged(other.getIsChanged());
- }
- if (other.hasMustSendNotification()) {
- setMustSendNotification(other.getMustSendNotification());
- }
- this.mergeUnknownFields(other.getUnknownFields());
- return this;
- }
-
- public final boolean isInitialized() {
- return true;
- }
-
- public Builder mergeFrom(
- com.google.protobuf.CodedInputStream input,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws java.io.IOException {
- org.sonar.batch.protocol.output.BatchReport.Issue parsedMessage = null;
- try {
- parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- parsedMessage = (org.sonar.batch.protocol.output.BatchReport.Issue) e.getUnfinishedMessage();
- throw e;
- } finally {
- if (parsedMessage != null) {
- mergeFrom(parsedMessage);
- }
- }
- return this;
- }
- private int bitField0_;
-
- private java.lang.Object ruleRepository_ = "";
- /**
- * <code>optional string rule_repository = 1;</code>
- */
- public boolean hasRuleRepository() {
- return ((bitField0_ & 0x00000001) == 0x00000001);
- }
- /**
- * <code>optional string rule_repository = 1;</code>
- */
- public java.lang.String getRuleRepository() {
- java.lang.Object ref = ruleRepository_;
- if (!(ref instanceof java.lang.String)) {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- ruleRepository_ = s;
- }
- return s;
- } else {
- return (java.lang.String) ref;
- }
- }
- /**
- * <code>optional string rule_repository = 1;</code>
- */
- public com.google.protobuf.ByteString
- getRuleRepositoryBytes() {
- java.lang.Object ref = ruleRepository_;
- if (ref instanceof String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- ruleRepository_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
- }
- /**
- * <code>optional string rule_repository = 1;</code>
- */
- public Builder setRuleRepository(
- java.lang.String value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000001;
- ruleRepository_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional string rule_repository = 1;</code>
- */
- public Builder clearRuleRepository() {
- bitField0_ = (bitField0_ & ~0x00000001);
- ruleRepository_ = getDefaultInstance().getRuleRepository();
- onChanged();
- return this;
- }
- /**
- * <code>optional string rule_repository = 1;</code>
- */
- public Builder setRuleRepositoryBytes(
- com.google.protobuf.ByteString value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000001;
- ruleRepository_ = value;
- onChanged();
- return this;
- }
-
- private java.lang.Object ruleKey_ = "";
- /**
- * <code>optional string rule_key = 2;</code>
- */
- public boolean hasRuleKey() {
- return ((bitField0_ & 0x00000002) == 0x00000002);
- }
- /**
- * <code>optional string rule_key = 2;</code>
- */
- public java.lang.String getRuleKey() {
- java.lang.Object ref = ruleKey_;
- if (!(ref instanceof java.lang.String)) {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- ruleKey_ = s;
- }
- return s;
- } else {
- return (java.lang.String) ref;
- }
- }
- /**
- * <code>optional string rule_key = 2;</code>
- */
- public com.google.protobuf.ByteString
- getRuleKeyBytes() {
- java.lang.Object ref = ruleKey_;
- if (ref instanceof String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- ruleKey_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
- }
- /**
- * <code>optional string rule_key = 2;</code>
- */
- public Builder setRuleKey(
- java.lang.String value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000002;
- ruleKey_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional string rule_key = 2;</code>
- */
- public Builder clearRuleKey() {
- bitField0_ = (bitField0_ & ~0x00000002);
- ruleKey_ = getDefaultInstance().getRuleKey();
- onChanged();
- return this;
- }
- /**
- * <code>optional string rule_key = 2;</code>
- */
- public Builder setRuleKeyBytes(
- com.google.protobuf.ByteString value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000002;
- ruleKey_ = value;
- onChanged();
- return this;
- }
-
- private int line_ ;
- /**
- * <code>optional int32 line = 3;</code>
- */
- public boolean hasLine() {
- return ((bitField0_ & 0x00000004) == 0x00000004);
- }
- /**
- * <code>optional int32 line = 3;</code>
- */
- public int getLine() {
- return line_;
- }
- /**
- * <code>optional int32 line = 3;</code>
- */
- public Builder setLine(int value) {
- bitField0_ |= 0x00000004;
- line_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional int32 line = 3;</code>
- */
- public Builder clearLine() {
- bitField0_ = (bitField0_ & ~0x00000004);
- line_ = 0;
- onChanged();
- return this;
- }
-
- private java.lang.Object msg_ = "";
- /**
- * <code>optional string msg = 4;</code>
- */
- public boolean hasMsg() {
- return ((bitField0_ & 0x00000008) == 0x00000008);
- }
- /**
- * <code>optional string msg = 4;</code>
- */
- public java.lang.String getMsg() {
- java.lang.Object ref = msg_;
- if (!(ref instanceof java.lang.String)) {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- msg_ = s;
- }
- return s;
- } else {
- return (java.lang.String) ref;
- }
- }
- /**
- * <code>optional string msg = 4;</code>
- */
- public com.google.protobuf.ByteString
- getMsgBytes() {
- java.lang.Object ref = msg_;
- if (ref instanceof String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- msg_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
- }
- /**
- * <code>optional string msg = 4;</code>
- */
- public Builder setMsg(
- java.lang.String value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000008;
- msg_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional string msg = 4;</code>
- */
- public Builder clearMsg() {
- bitField0_ = (bitField0_ & ~0x00000008);
- msg_ = getDefaultInstance().getMsg();
- onChanged();
- return this;
- }
- /**
- * <code>optional string msg = 4;</code>
- */
- public Builder setMsgBytes(
- com.google.protobuf.ByteString value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000008;
- msg_ = value;
- onChanged();
- return this;
- }
-
- private org.sonar.batch.protocol.Constants.Severity severity_ = org.sonar.batch.protocol.Constants.Severity.INFO;
- /**
- * <code>optional .Severity severity = 5;</code>
- */
- public boolean hasSeverity() {
- return ((bitField0_ & 0x00000010) == 0x00000010);
- }
- /**
- * <code>optional .Severity severity = 5;</code>
- */
- public org.sonar.batch.protocol.Constants.Severity getSeverity() {
- return severity_;
- }
- /**
- * <code>optional .Severity severity = 5;</code>
- */
- public Builder setSeverity(org.sonar.batch.protocol.Constants.Severity value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000010;
- severity_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional .Severity severity = 5;</code>
- */
- public Builder clearSeverity() {
- bitField0_ = (bitField0_ & ~0x00000010);
- severity_ = org.sonar.batch.protocol.Constants.Severity.INFO;
- onChanged();
- return this;
- }
-
- private com.google.protobuf.LazyStringList tag_ = com.google.protobuf.LazyStringArrayList.EMPTY;
- private void ensureTagIsMutable() {
- if (!((bitField0_ & 0x00000020) == 0x00000020)) {
- tag_ = new com.google.protobuf.LazyStringArrayList(tag_);
- bitField0_ |= 0x00000020;
- }
- }
- /**
- * <code>repeated string tag = 6;</code>
- */
- public com.google.protobuf.ProtocolStringList
- getTagList() {
- return tag_.getUnmodifiableView();
- }
- /**
- * <code>repeated string tag = 6;</code>
- */
- public int getTagCount() {
- return tag_.size();
- }
- /**
- * <code>repeated string tag = 6;</code>
- */
- public java.lang.String getTag(int index) {
- return tag_.get(index);
- }
- /**
- * <code>repeated string tag = 6;</code>
- */
- public com.google.protobuf.ByteString
- getTagBytes(int index) {
- return tag_.getByteString(index);
- }
- /**
- * <code>repeated string tag = 6;</code>
- */
- public Builder setTag(
- int index, java.lang.String value) {
- if (value == null) {
- throw new NullPointerException();
- }
- ensureTagIsMutable();
- tag_.set(index, value);
- onChanged();
- return this;
- }
- /**
- * <code>repeated string tag = 6;</code>
- */
- public Builder addTag(
- java.lang.String value) {
- if (value == null) {
- throw new NullPointerException();
- }
- ensureTagIsMutable();
- tag_.add(value);
- onChanged();
- return this;
- }
- /**
- * <code>repeated string tag = 6;</code>
- */
- public Builder addAllTag(
- java.lang.Iterable<java.lang.String> values) {
- ensureTagIsMutable();
- com.google.protobuf.AbstractMessageLite.Builder.addAll(
- values, tag_);
- onChanged();
- return this;
- }
- /**
- * <code>repeated string tag = 6;</code>
- */
- public Builder clearTag() {
- tag_ = com.google.protobuf.LazyStringArrayList.EMPTY;
- bitField0_ = (bitField0_ & ~0x00000020);
- onChanged();
- return this;
- }
- /**
- * <code>repeated string tag = 6;</code>
- */
- public Builder addTagBytes(
- com.google.protobuf.ByteString value) {
- if (value == null) {
- throw new NullPointerException();
- }
- ensureTagIsMutable();
- tag_.add(value);
- onChanged();
- return this;
- }
-
- private double effortToFix_ ;
- /**
- * <code>optional double effort_to_fix = 7;</code>
- *
- * <pre>
- * temporary fields during development of computation stack
- * </pre>
- */
- public boolean hasEffortToFix() {
- return ((bitField0_ & 0x00000040) == 0x00000040);
- }
- /**
- * <code>optional double effort_to_fix = 7;</code>
- *
- * <pre>
- * temporary fields during development of computation stack
- * </pre>
- */
- public double getEffortToFix() {
- return effortToFix_;
- }
- /**
- * <code>optional double effort_to_fix = 7;</code>
- *
- * <pre>
- * temporary fields during development of computation stack
- * </pre>
- */
- public Builder setEffortToFix(double value) {
- bitField0_ |= 0x00000040;
- effortToFix_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional double effort_to_fix = 7;</code>
- *
- * <pre>
- * temporary fields during development of computation stack
- * </pre>
- */
- public Builder clearEffortToFix() {
- bitField0_ = (bitField0_ & ~0x00000040);
- effortToFix_ = 0D;
- onChanged();
- return this;
- }
-
- private boolean isNew_ ;
- /**
- * <code>optional bool is_new = 8;</code>
- */
- public boolean hasIsNew() {
- return ((bitField0_ & 0x00000080) == 0x00000080);
- }
- /**
- * <code>optional bool is_new = 8;</code>
- */
- public boolean getIsNew() {
- return isNew_;
- }
- /**
- * <code>optional bool is_new = 8;</code>
- */
- public Builder setIsNew(boolean value) {
- bitField0_ |= 0x00000080;
- isNew_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional bool is_new = 8;</code>
- */
- public Builder clearIsNew() {
- bitField0_ = (bitField0_ & ~0x00000080);
- isNew_ = false;
- onChanged();
- return this;
- }
-
- private java.lang.Object uuid_ = "";
- /**
- * <code>optional string uuid = 9;</code>
- */
- public boolean hasUuid() {
- return ((bitField0_ & 0x00000100) == 0x00000100);
- }
- /**
- * <code>optional string uuid = 9;</code>
- */
- public java.lang.String getUuid() {
- java.lang.Object ref = uuid_;
- if (!(ref instanceof java.lang.String)) {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- uuid_ = s;
- }
- return s;
- } else {
- return (java.lang.String) ref;
- }
- }
- /**
- * <code>optional string uuid = 9;</code>
- */
- public com.google.protobuf.ByteString
- getUuidBytes() {
- java.lang.Object ref = uuid_;
- if (ref instanceof String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- uuid_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
- }
- /**
- * <code>optional string uuid = 9;</code>
- */
- public Builder setUuid(
- java.lang.String value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000100;
- uuid_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional string uuid = 9;</code>
- */
- public Builder clearUuid() {
- bitField0_ = (bitField0_ & ~0x00000100);
- uuid_ = getDefaultInstance().getUuid();
- onChanged();
- return this;
- }
- /**
- * <code>optional string uuid = 9;</code>
- */
- public Builder setUuidBytes(
- com.google.protobuf.ByteString value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000100;
- uuid_ = value;
- onChanged();
- return this;
- }
-
- private long debtInMinutes_ ;
- /**
- * <code>optional int64 debt_in_minutes = 10;</code>
- */
- public boolean hasDebtInMinutes() {
- return ((bitField0_ & 0x00000200) == 0x00000200);
- }
- /**
- * <code>optional int64 debt_in_minutes = 10;</code>
- */
- public long getDebtInMinutes() {
- return debtInMinutes_;
- }
- /**
- * <code>optional int64 debt_in_minutes = 10;</code>
- */
- public Builder setDebtInMinutes(long value) {
- bitField0_ |= 0x00000200;
- debtInMinutes_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional int64 debt_in_minutes = 10;</code>
- */
- public Builder clearDebtInMinutes() {
- bitField0_ = (bitField0_ & ~0x00000200);
- debtInMinutes_ = 0L;
- onChanged();
- return this;
- }
-
- private java.lang.Object resolution_ = "";
- /**
- * <code>optional string resolution = 11;</code>
- */
- public boolean hasResolution() {
- return ((bitField0_ & 0x00000400) == 0x00000400);
- }
- /**
- * <code>optional string resolution = 11;</code>
- */
- public java.lang.String getResolution() {
- java.lang.Object ref = resolution_;
- if (!(ref instanceof java.lang.String)) {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- resolution_ = s;
- }
- return s;
- } else {
- return (java.lang.String) ref;
- }
- }
- /**
- * <code>optional string resolution = 11;</code>
- */
- public com.google.protobuf.ByteString
- getResolutionBytes() {
- java.lang.Object ref = resolution_;
- if (ref instanceof String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- resolution_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
- }
- /**
- * <code>optional string resolution = 11;</code>
- */
- public Builder setResolution(
- java.lang.String value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000400;
- resolution_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional string resolution = 11;</code>
- */
- public Builder clearResolution() {
- bitField0_ = (bitField0_ & ~0x00000400);
- resolution_ = getDefaultInstance().getResolution();
- onChanged();
+ public Builder clear() {
+ super.clear();
+ ruleRepository_ = "";
+ bitField0_ = (bitField0_ & ~0x00000001);
+ ruleKey_ = "";
+ bitField0_ = (bitField0_ & ~0x00000002);
+ line_ = 0;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ msg_ = "";
+ bitField0_ = (bitField0_ & ~0x00000008);
+ severity_ = org.sonar.batch.protocol.Constants.Severity.INFO;
+ bitField0_ = (bitField0_ & ~0x00000010);
+ tag_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000020);
+ effortToFix_ = 0D;
+ bitField0_ = (bitField0_ & ~0x00000040);
+ attributes_ = "";
+ bitField0_ = (bitField0_ & ~0x00000080);
+ debtInMinutes_ = 0L;
+ bitField0_ = (bitField0_ & ~0x00000100);
return this;
}
- /**
- * <code>optional string resolution = 11;</code>
- */
- public Builder setResolutionBytes(
- com.google.protobuf.ByteString value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000400;
- resolution_ = value;
- onChanged();
- return this;
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
}
- private java.lang.Object status_ = "";
- /**
- * <code>optional string status = 12;</code>
- */
- public boolean hasStatus() {
- return ((bitField0_ & 0x00000800) == 0x00000800);
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return org.sonar.batch.protocol.output.BatchReport.internal_static_Issue_descriptor;
}
- /**
- * <code>optional string status = 12;</code>
- */
- public java.lang.String getStatus() {
- java.lang.Object ref = status_;
- if (!(ref instanceof java.lang.String)) {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- status_ = s;
- }
- return s;
- } else {
- return (java.lang.String) ref;
- }
+
+ public org.sonar.batch.protocol.output.BatchReport.Issue getDefaultInstanceForType() {
+ return org.sonar.batch.protocol.output.BatchReport.Issue.getDefaultInstance();
}
- /**
- * <code>optional string status = 12;</code>
- */
- public com.google.protobuf.ByteString
- getStatusBytes() {
- java.lang.Object ref = status_;
- if (ref instanceof String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- status_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
+
+ public org.sonar.batch.protocol.output.BatchReport.Issue build() {
+ org.sonar.batch.protocol.output.BatchReport.Issue result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
}
- }
- /**
- * <code>optional string status = 12;</code>
- */
- public Builder setStatus(
- java.lang.String value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000800;
- status_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional string status = 12;</code>
- */
- public Builder clearStatus() {
- bitField0_ = (bitField0_ & ~0x00000800);
- status_ = getDefaultInstance().getStatus();
- onChanged();
- return this;
- }
- /**
- * <code>optional string status = 12;</code>
- */
- public Builder setStatusBytes(
- com.google.protobuf.ByteString value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000800;
- status_ = value;
- onChanged();
- return this;
+ return result;
}
- private java.lang.Object checksum_ = "";
- /**
- * <code>optional string checksum = 13;</code>
- */
- public boolean hasChecksum() {
- return ((bitField0_ & 0x00001000) == 0x00001000);
- }
- /**
- * <code>optional string checksum = 13;</code>
- */
- public java.lang.String getChecksum() {
- java.lang.Object ref = checksum_;
- if (!(ref instanceof java.lang.String)) {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- checksum_ = s;
- }
- return s;
- } else {
- return (java.lang.String) ref;
+ public org.sonar.batch.protocol.output.BatchReport.Issue buildPartial() {
+ org.sonar.batch.protocol.output.BatchReport.Issue result = new org.sonar.batch.protocol.output.BatchReport.Issue(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.ruleRepository_ = ruleRepository_;
+ if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+ to_bitField0_ |= 0x00000002;
+ }
+ result.ruleKey_ = ruleKey_;
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000004;
+ }
+ result.line_ = line_;
+ if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+ to_bitField0_ |= 0x00000008;
+ }
+ result.msg_ = msg_;
+ if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+ to_bitField0_ |= 0x00000010;
+ }
+ result.severity_ = severity_;
+ if (((bitField0_ & 0x00000020) == 0x00000020)) {
+ tag_ = tag_.getUnmodifiableView();
+ bitField0_ = (bitField0_ & ~0x00000020);
+ }
+ result.tag_ = tag_;
+ if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
+ to_bitField0_ |= 0x00000020;
+ }
+ result.effortToFix_ = effortToFix_;
+ if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
+ to_bitField0_ |= 0x00000040;
+ }
+ result.attributes_ = attributes_;
+ if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
+ to_bitField0_ |= 0x00000080;
}
+ result.debtInMinutes_ = debtInMinutes_;
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
}
- /**
- * <code>optional string checksum = 13;</code>
- */
- public com.google.protobuf.ByteString
- getChecksumBytes() {
- java.lang.Object ref = checksum_;
- if (ref instanceof String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- checksum_ = b;
- return b;
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof org.sonar.batch.protocol.output.BatchReport.Issue) {
+ return mergeFrom((org.sonar.batch.protocol.output.BatchReport.Issue)other);
} else {
- return (com.google.protobuf.ByteString) ref;
+ super.mergeFrom(other);
+ return this;
}
}
- /**
- * <code>optional string checksum = 13;</code>
- */
- public Builder setChecksum(
- java.lang.String value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00001000;
- checksum_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional string checksum = 13;</code>
- */
- public Builder clearChecksum() {
- bitField0_ = (bitField0_ & ~0x00001000);
- checksum_ = getDefaultInstance().getChecksum();
- onChanged();
- return this;
- }
- /**
- * <code>optional string checksum = 13;</code>
- */
- public Builder setChecksumBytes(
- com.google.protobuf.ByteString value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00001000;
- checksum_ = value;
- onChanged();
- return this;
- }
- private boolean manualSeverity_ ;
- /**
- * <code>optional bool manual_severity = 14;</code>
- */
- public boolean hasManualSeverity() {
- return ((bitField0_ & 0x00002000) == 0x00002000);
- }
- /**
- * <code>optional bool manual_severity = 14;</code>
- */
- public boolean getManualSeverity() {
- return manualSeverity_;
- }
- /**
- * <code>optional bool manual_severity = 14;</code>
- */
- public Builder setManualSeverity(boolean value) {
- bitField0_ |= 0x00002000;
- manualSeverity_ = value;
- onChanged();
+ public Builder mergeFrom(org.sonar.batch.protocol.output.BatchReport.Issue other) {
+ if (other == org.sonar.batch.protocol.output.BatchReport.Issue.getDefaultInstance()) return this;
+ if (other.hasRuleRepository()) {
+ bitField0_ |= 0x00000001;
+ ruleRepository_ = other.ruleRepository_;
+ onChanged();
+ }
+ if (other.hasRuleKey()) {
+ bitField0_ |= 0x00000002;
+ ruleKey_ = other.ruleKey_;
+ onChanged();
+ }
+ if (other.hasLine()) {
+ setLine(other.getLine());
+ }
+ if (other.hasMsg()) {
+ bitField0_ |= 0x00000008;
+ msg_ = other.msg_;
+ onChanged();
+ }
+ if (other.hasSeverity()) {
+ setSeverity(other.getSeverity());
+ }
+ if (!other.tag_.isEmpty()) {
+ if (tag_.isEmpty()) {
+ tag_ = other.tag_;
+ bitField0_ = (bitField0_ & ~0x00000020);
+ } else {
+ ensureTagIsMutable();
+ tag_.addAll(other.tag_);
+ }
+ onChanged();
+ }
+ if (other.hasEffortToFix()) {
+ setEffortToFix(other.getEffortToFix());
+ }
+ if (other.hasAttributes()) {
+ bitField0_ |= 0x00000080;
+ attributes_ = other.attributes_;
+ onChanged();
+ }
+ if (other.hasDebtInMinutes()) {
+ setDebtInMinutes(other.getDebtInMinutes());
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
return this;
}
- /**
- * <code>optional bool manual_severity = 14;</code>
- */
- public Builder clearManualSeverity() {
- bitField0_ = (bitField0_ & ~0x00002000);
- manualSeverity_ = false;
- onChanged();
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ org.sonar.batch.protocol.output.BatchReport.Issue parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (org.sonar.batch.protocol.output.BatchReport.Issue) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
return this;
}
+ private int bitField0_;
- private java.lang.Object reporter_ = "";
+ private java.lang.Object ruleRepository_ = "";
/**
- * <code>optional string reporter = 15;</code>
+ * <code>optional string rule_repository = 1;</code>
*/
- public boolean hasReporter() {
- return ((bitField0_ & 0x00004000) == 0x00004000);
+ public boolean hasRuleRepository() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
}
/**
- * <code>optional string reporter = 15;</code>
+ * <code>optional string rule_repository = 1;</code>
*/
- public java.lang.String getReporter() {
- java.lang.Object ref = reporter_;
+ public java.lang.String getRuleRepository() {
+ java.lang.Object ref = ruleRepository_;
if (!(ref instanceof java.lang.String)) {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
if (bs.isValidUtf8()) {
- reporter_ = s;
+ ruleRepository_ = s;
}
return s;
} else {
}
}
/**
- * <code>optional string reporter = 15;</code>
+ * <code>optional string rule_repository = 1;</code>
*/
public com.google.protobuf.ByteString
- getReporterBytes() {
- java.lang.Object ref = reporter_;
+ getRuleRepositoryBytes() {
+ java.lang.Object ref = ruleRepository_;
if (ref instanceof String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8(
(java.lang.String) ref);
- reporter_ = b;
+ ruleRepository_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
/**
- * <code>optional string reporter = 15;</code>
+ * <code>optional string rule_repository = 1;</code>
*/
- public Builder setReporter(
+ public Builder setRuleRepository(
java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
- bitField0_ |= 0x00004000;
- reporter_ = value;
+ bitField0_ |= 0x00000001;
+ ruleRepository_ = value;
onChanged();
return this;
}
/**
- * <code>optional string reporter = 15;</code>
+ * <code>optional string rule_repository = 1;</code>
*/
- public Builder clearReporter() {
- bitField0_ = (bitField0_ & ~0x00004000);
- reporter_ = getDefaultInstance().getReporter();
+ public Builder clearRuleRepository() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ ruleRepository_ = getDefaultInstance().getRuleRepository();
onChanged();
return this;
}
/**
- * <code>optional string reporter = 15;</code>
+ * <code>optional string rule_repository = 1;</code>
*/
- public Builder setReporterBytes(
+ public Builder setRuleRepositoryBytes(
com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
- bitField0_ |= 0x00004000;
- reporter_ = value;
+ bitField0_ |= 0x00000001;
+ ruleRepository_ = value;
onChanged();
return this;
}
- private java.lang.Object assignee_ = "";
+ private java.lang.Object ruleKey_ = "";
/**
- * <code>optional string assignee = 16;</code>
+ * <code>optional string rule_key = 2;</code>
*/
- public boolean hasAssignee() {
- return ((bitField0_ & 0x00008000) == 0x00008000);
+ public boolean hasRuleKey() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
}
/**
- * <code>optional string assignee = 16;</code>
+ * <code>optional string rule_key = 2;</code>
*/
- public java.lang.String getAssignee() {
- java.lang.Object ref = assignee_;
+ public java.lang.String getRuleKey() {
+ java.lang.Object ref = ruleKey_;
if (!(ref instanceof java.lang.String)) {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
if (bs.isValidUtf8()) {
- assignee_ = s;
+ ruleKey_ = s;
}
return s;
} else {
}
}
/**
- * <code>optional string assignee = 16;</code>
+ * <code>optional string rule_key = 2;</code>
*/
public com.google.protobuf.ByteString
- getAssigneeBytes() {
- java.lang.Object ref = assignee_;
+ getRuleKeyBytes() {
+ java.lang.Object ref = ruleKey_;
if (ref instanceof String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8(
(java.lang.String) ref);
- assignee_ = b;
+ ruleKey_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
/**
- * <code>optional string assignee = 16;</code>
+ * <code>optional string rule_key = 2;</code>
*/
- public Builder setAssignee(
+ public Builder setRuleKey(
java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
- bitField0_ |= 0x00008000;
- assignee_ = value;
+ bitField0_ |= 0x00000002;
+ ruleKey_ = value;
onChanged();
return this;
}
/**
- * <code>optional string assignee = 16;</code>
+ * <code>optional string rule_key = 2;</code>
*/
- public Builder clearAssignee() {
- bitField0_ = (bitField0_ & ~0x00008000);
- assignee_ = getDefaultInstance().getAssignee();
+ public Builder clearRuleKey() {
+ bitField0_ = (bitField0_ & ~0x00000002);
+ ruleKey_ = getDefaultInstance().getRuleKey();
onChanged();
return this;
}
/**
- * <code>optional string assignee = 16;</code>
+ * <code>optional string rule_key = 2;</code>
*/
- public Builder setAssigneeBytes(
+ public Builder setRuleKeyBytes(
com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
- bitField0_ |= 0x00008000;
- assignee_ = value;
+ bitField0_ |= 0x00000002;
+ ruleKey_ = value;
onChanged();
return this;
}
- private java.lang.Object actionPlanKey_ = "";
- /**
- * <code>optional string action_plan_key = 17;</code>
- */
- public boolean hasActionPlanKey() {
- return ((bitField0_ & 0x00010000) == 0x00010000);
- }
- /**
- * <code>optional string action_plan_key = 17;</code>
- */
- public java.lang.String getActionPlanKey() {
- java.lang.Object ref = actionPlanKey_;
- if (!(ref instanceof java.lang.String)) {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- actionPlanKey_ = s;
- }
- return s;
- } else {
- return (java.lang.String) ref;
- }
- }
+ private int line_ ;
/**
- * <code>optional string action_plan_key = 17;</code>
+ * <code>optional int32 line = 3;</code>
*/
- public com.google.protobuf.ByteString
- getActionPlanKeyBytes() {
- java.lang.Object ref = actionPlanKey_;
- if (ref instanceof String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- actionPlanKey_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
+ public boolean hasLine() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
}
/**
- * <code>optional string action_plan_key = 17;</code>
+ * <code>optional int32 line = 3;</code>
*/
- public Builder setActionPlanKey(
- java.lang.String value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00010000;
- actionPlanKey_ = value;
- onChanged();
- return this;
+ public int getLine() {
+ return line_;
}
/**
- * <code>optional string action_plan_key = 17;</code>
+ * <code>optional int32 line = 3;</code>
*/
- public Builder clearActionPlanKey() {
- bitField0_ = (bitField0_ & ~0x00010000);
- actionPlanKey_ = getDefaultInstance().getActionPlanKey();
+ public Builder setLine(int value) {
+ bitField0_ |= 0x00000004;
+ line_ = value;
onChanged();
return this;
}
/**
- * <code>optional string action_plan_key = 17;</code>
+ * <code>optional int32 line = 3;</code>
*/
- public Builder setActionPlanKeyBytes(
- com.google.protobuf.ByteString value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00010000;
- actionPlanKey_ = value;
+ public Builder clearLine() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ line_ = 0;
onChanged();
return this;
}
- private java.lang.Object attributes_ = "";
+ private java.lang.Object msg_ = "";
/**
- * <code>optional string attributes = 18;</code>
+ * <code>optional string msg = 4;</code>
*/
- public boolean hasAttributes() {
- return ((bitField0_ & 0x00020000) == 0x00020000);
+ public boolean hasMsg() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
}
/**
- * <code>optional string attributes = 18;</code>
+ * <code>optional string msg = 4;</code>
*/
- public java.lang.String getAttributes() {
- java.lang.Object ref = attributes_;
+ public java.lang.String getMsg() {
+ java.lang.Object ref = msg_;
if (!(ref instanceof java.lang.String)) {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
if (bs.isValidUtf8()) {
- attributes_ = s;
+ msg_ = s;
}
return s;
} else {
}
}
/**
- * <code>optional string attributes = 18;</code>
+ * <code>optional string msg = 4;</code>
*/
public com.google.protobuf.ByteString
- getAttributesBytes() {
- java.lang.Object ref = attributes_;
+ getMsgBytes() {
+ java.lang.Object ref = msg_;
if (ref instanceof String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8(
(java.lang.String) ref);
- attributes_ = b;
+ msg_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
/**
- * <code>optional string attributes = 18;</code>
+ * <code>optional string msg = 4;</code>
*/
- public Builder setAttributes(
+ public Builder setMsg(
java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
- bitField0_ |= 0x00020000;
- attributes_ = value;
+ bitField0_ |= 0x00000008;
+ msg_ = value;
onChanged();
return this;
}
/**
- * <code>optional string attributes = 18;</code>
+ * <code>optional string msg = 4;</code>
*/
- public Builder clearAttributes() {
- bitField0_ = (bitField0_ & ~0x00020000);
- attributes_ = getDefaultInstance().getAttributes();
+ public Builder clearMsg() {
+ bitField0_ = (bitField0_ & ~0x00000008);
+ msg_ = getDefaultInstance().getMsg();
onChanged();
return this;
}
/**
- * <code>optional string attributes = 18;</code>
+ * <code>optional string msg = 4;</code>
*/
- public Builder setAttributesBytes(
+ public Builder setMsgBytes(
com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
- bitField0_ |= 0x00020000;
- attributes_ = value;
+ bitField0_ |= 0x00000008;
+ msg_ = value;
onChanged();
return this;
}
- private java.lang.Object authorLogin_ = "";
- /**
- * <code>optional string author_login = 19;</code>
- */
- public boolean hasAuthorLogin() {
- return ((bitField0_ & 0x00040000) == 0x00040000);
- }
+ private org.sonar.batch.protocol.Constants.Severity severity_ = org.sonar.batch.protocol.Constants.Severity.INFO;
/**
- * <code>optional string author_login = 19;</code>
+ * <code>optional .Severity severity = 5;</code>
*/
- public java.lang.String getAuthorLogin() {
- java.lang.Object ref = authorLogin_;
- if (!(ref instanceof java.lang.String)) {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- authorLogin_ = s;
- }
- return s;
- } else {
- return (java.lang.String) ref;
- }
+ public boolean hasSeverity() {
+ return ((bitField0_ & 0x00000010) == 0x00000010);
}
/**
- * <code>optional string author_login = 19;</code>
+ * <code>optional .Severity severity = 5;</code>
*/
- public com.google.protobuf.ByteString
- getAuthorLoginBytes() {
- java.lang.Object ref = authorLogin_;
- if (ref instanceof String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- authorLogin_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
+ public org.sonar.batch.protocol.Constants.Severity getSeverity() {
+ return severity_;
}
/**
- * <code>optional string author_login = 19;</code>
+ * <code>optional .Severity severity = 5;</code>
*/
- public Builder setAuthorLogin(
- java.lang.String value) {
+ public Builder setSeverity(org.sonar.batch.protocol.Constants.Severity value) {
if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00040000;
- authorLogin_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional string author_login = 19;</code>
- */
- public Builder clearAuthorLogin() {
- bitField0_ = (bitField0_ & ~0x00040000);
- authorLogin_ = getDefaultInstance().getAuthorLogin();
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000010;
+ severity_ = value;
onChanged();
return this;
}
/**
- * <code>optional string author_login = 19;</code>
+ * <code>optional .Severity severity = 5;</code>
*/
- public Builder setAuthorLoginBytes(
- com.google.protobuf.ByteString value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00040000;
- authorLogin_ = value;
+ public Builder clearSeverity() {
+ bitField0_ = (bitField0_ & ~0x00000010);
+ severity_ = org.sonar.batch.protocol.Constants.Severity.INFO;
onChanged();
return this;
}
- private long creationDate_ ;
- /**
- * <code>optional int64 creation_date = 20;</code>
- */
- public boolean hasCreationDate() {
- return ((bitField0_ & 0x00080000) == 0x00080000);
- }
- /**
- * <code>optional int64 creation_date = 20;</code>
- */
- public long getCreationDate() {
- return creationDate_;
+ private com.google.protobuf.LazyStringList tag_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+ private void ensureTagIsMutable() {
+ if (!((bitField0_ & 0x00000020) == 0x00000020)) {
+ tag_ = new com.google.protobuf.LazyStringArrayList(tag_);
+ bitField0_ |= 0x00000020;
+ }
}
/**
- * <code>optional int64 creation_date = 20;</code>
+ * <code>repeated string tag = 6;</code>
*/
- public Builder setCreationDate(long value) {
- bitField0_ |= 0x00080000;
- creationDate_ = value;
- onChanged();
- return this;
+ public com.google.protobuf.ProtocolStringList
+ getTagList() {
+ return tag_.getUnmodifiableView();
}
/**
- * <code>optional int64 creation_date = 20;</code>
+ * <code>repeated string tag = 6;</code>
*/
- public Builder clearCreationDate() {
- bitField0_ = (bitField0_ & ~0x00080000);
- creationDate_ = 0L;
- onChanged();
- return this;
+ public int getTagCount() {
+ return tag_.size();
}
-
- private long closeDate_ ;
/**
- * <code>optional int64 close_date = 21;</code>
+ * <code>repeated string tag = 6;</code>
*/
- public boolean hasCloseDate() {
- return ((bitField0_ & 0x00100000) == 0x00100000);
+ public java.lang.String getTag(int index) {
+ return tag_.get(index);
}
/**
- * <code>optional int64 close_date = 21;</code>
+ * <code>repeated string tag = 6;</code>
*/
- public long getCloseDate() {
- return closeDate_;
+ public com.google.protobuf.ByteString
+ getTagBytes(int index) {
+ return tag_.getByteString(index);
}
/**
- * <code>optional int64 close_date = 21;</code>
+ * <code>repeated string tag = 6;</code>
*/
- public Builder setCloseDate(long value) {
- bitField0_ |= 0x00100000;
- closeDate_ = value;
+ public Builder setTag(
+ int index, java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTagIsMutable();
+ tag_.set(index, value);
onChanged();
return this;
}
/**
- * <code>optional int64 close_date = 21;</code>
+ * <code>repeated string tag = 6;</code>
*/
- public Builder clearCloseDate() {
- bitField0_ = (bitField0_ & ~0x00100000);
- closeDate_ = 0L;
+ public Builder addTag(
+ java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTagIsMutable();
+ tag_.add(value);
onChanged();
return this;
}
-
- private long updateDate_ ;
- /**
- * <code>optional int64 update_date = 22;</code>
- */
- public boolean hasUpdateDate() {
- return ((bitField0_ & 0x00200000) == 0x00200000);
- }
/**
- * <code>optional int64 update_date = 22;</code>
+ * <code>repeated string tag = 6;</code>
*/
- public long getUpdateDate() {
- return updateDate_;
+ public Builder addAllTag(
+ java.lang.Iterable<java.lang.String> values) {
+ ensureTagIsMutable();
+ com.google.protobuf.AbstractMessageLite.Builder.addAll(
+ values, tag_);
+ onChanged();
+ return this;
}
/**
- * <code>optional int64 update_date = 22;</code>
+ * <code>repeated string tag = 6;</code>
*/
- public Builder setUpdateDate(long value) {
- bitField0_ |= 0x00200000;
- updateDate_ = value;
+ public Builder clearTag() {
+ tag_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000020);
onChanged();
return this;
}
/**
- * <code>optional int64 update_date = 22;</code>
+ * <code>repeated string tag = 6;</code>
*/
- public Builder clearUpdateDate() {
- bitField0_ = (bitField0_ & ~0x00200000);
- updateDate_ = 0L;
+ public Builder addTagBytes(
+ com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureTagIsMutable();
+ tag_.add(value);
onChanged();
return this;
}
- private long selectedAt_ ;
+ private double effortToFix_ ;
/**
- * <code>optional int64 selected_at = 23;</code>
+ * <code>optional double effort_to_fix = 7;</code>
*/
- public boolean hasSelectedAt() {
- return ((bitField0_ & 0x00400000) == 0x00400000);
+ public boolean hasEffortToFix() {
+ return ((bitField0_ & 0x00000040) == 0x00000040);
}
/**
- * <code>optional int64 selected_at = 23;</code>
+ * <code>optional double effort_to_fix = 7;</code>
*/
- public long getSelectedAt() {
- return selectedAt_;
+ public double getEffortToFix() {
+ return effortToFix_;
}
/**
- * <code>optional int64 selected_at = 23;</code>
+ * <code>optional double effort_to_fix = 7;</code>
*/
- public Builder setSelectedAt(long value) {
- bitField0_ |= 0x00400000;
- selectedAt_ = value;
+ public Builder setEffortToFix(double value) {
+ bitField0_ |= 0x00000040;
+ effortToFix_ = value;
onChanged();
return this;
}
/**
- * <code>optional int64 selected_at = 23;</code>
+ * <code>optional double effort_to_fix = 7;</code>
*/
- public Builder clearSelectedAt() {
- bitField0_ = (bitField0_ & ~0x00400000);
- selectedAt_ = 0L;
+ public Builder clearEffortToFix() {
+ bitField0_ = (bitField0_ & ~0x00000040);
+ effortToFix_ = 0D;
onChanged();
return this;
}
- private java.lang.Object diffFields_ = "";
+ private java.lang.Object attributes_ = "";
/**
- * <code>optional string diff_fields = 24;</code>
+ * <code>optional string attributes = 8;</code>
*/
- public boolean hasDiffFields() {
- return ((bitField0_ & 0x00800000) == 0x00800000);
+ public boolean hasAttributes() {
+ return ((bitField0_ & 0x00000080) == 0x00000080);
}
/**
- * <code>optional string diff_fields = 24;</code>
+ * <code>optional string attributes = 8;</code>
*/
- public java.lang.String getDiffFields() {
- java.lang.Object ref = diffFields_;
+ public java.lang.String getAttributes() {
+ java.lang.Object ref = attributes_;
if (!(ref instanceof java.lang.String)) {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
if (bs.isValidUtf8()) {
- diffFields_ = s;
+ attributes_ = s;
}
return s;
} else {
}
}
/**
- * <code>optional string diff_fields = 24;</code>
+ * <code>optional string attributes = 8;</code>
*/
public com.google.protobuf.ByteString
- getDiffFieldsBytes() {
- java.lang.Object ref = diffFields_;
+ getAttributesBytes() {
+ java.lang.Object ref = attributes_;
if (ref instanceof String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8(
(java.lang.String) ref);
- diffFields_ = b;
+ attributes_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
/**
- * <code>optional string diff_fields = 24;</code>
+ * <code>optional string attributes = 8;</code>
*/
- public Builder setDiffFields(
+ public Builder setAttributes(
java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
- bitField0_ |= 0x00800000;
- diffFields_ = value;
+ bitField0_ |= 0x00000080;
+ attributes_ = value;
onChanged();
return this;
}
/**
- * <code>optional string diff_fields = 24;</code>
+ * <code>optional string attributes = 8;</code>
*/
- public Builder clearDiffFields() {
- bitField0_ = (bitField0_ & ~0x00800000);
- diffFields_ = getDefaultInstance().getDiffFields();
+ public Builder clearAttributes() {
+ bitField0_ = (bitField0_ & ~0x00000080);
+ attributes_ = getDefaultInstance().getAttributes();
onChanged();
return this;
}
/**
- * <code>optional string diff_fields = 24;</code>
+ * <code>optional string attributes = 8;</code>
*/
- public Builder setDiffFieldsBytes(
+ public Builder setAttributesBytes(
com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
- bitField0_ |= 0x00800000;
- diffFields_ = value;
- onChanged();
- return this;
- }
-
- private boolean isChanged_ ;
- /**
- * <code>optional bool is_changed = 25;</code>
- */
- public boolean hasIsChanged() {
- return ((bitField0_ & 0x01000000) == 0x01000000);
- }
- /**
- * <code>optional bool is_changed = 25;</code>
- */
- public boolean getIsChanged() {
- return isChanged_;
- }
- /**
- * <code>optional bool is_changed = 25;</code>
- */
- public Builder setIsChanged(boolean value) {
- bitField0_ |= 0x01000000;
- isChanged_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional bool is_changed = 25;</code>
- */
- public Builder clearIsChanged() {
- bitField0_ = (bitField0_ & ~0x01000000);
- isChanged_ = false;
+ bitField0_ |= 0x00000080;
+ attributes_ = value;
onChanged();
return this;
}
- private boolean mustSendNotification_ ;
+ private long debtInMinutes_ ;
/**
- * <code>optional bool must_send_notification = 26;</code>
+ * <code>optional int64 debt_in_minutes = 9;</code>
+ *
+ * <pre>
+ * TODO should it be moved to compute engine?
+ * </pre>
*/
- public boolean hasMustSendNotification() {
- return ((bitField0_ & 0x02000000) == 0x02000000);
+ public boolean hasDebtInMinutes() {
+ return ((bitField0_ & 0x00000100) == 0x00000100);
}
/**
- * <code>optional bool must_send_notification = 26;</code>
+ * <code>optional int64 debt_in_minutes = 9;</code>
+ *
+ * <pre>
+ * TODO should it be moved to compute engine?
+ * </pre>
*/
- public boolean getMustSendNotification() {
- return mustSendNotification_;
+ public long getDebtInMinutes() {
+ return debtInMinutes_;
}
/**
- * <code>optional bool must_send_notification = 26;</code>
+ * <code>optional int64 debt_in_minutes = 9;</code>
+ *
+ * <pre>
+ * TODO should it be moved to compute engine?
+ * </pre>
*/
- public Builder setMustSendNotification(boolean value) {
- bitField0_ |= 0x02000000;
- mustSendNotification_ = value;
+ public Builder setDebtInMinutes(long value) {
+ bitField0_ |= 0x00000100;
+ debtInMinutes_ = value;
onChanged();
return this;
}
/**
- * <code>optional bool must_send_notification = 26;</code>
+ * <code>optional int64 debt_in_minutes = 9;</code>
+ *
+ * <pre>
+ * TODO should it be moved to compute engine?
+ * </pre>
*/
- public Builder clearMustSendNotification() {
- bitField0_ = (bitField0_ & ~0x02000000);
- mustSendNotification_ = false;
+ public Builder clearDebtInMinutes() {
+ bitField0_ = (bitField0_ & ~0x00000100);
+ debtInMinutes_ = 0L;
onChanged();
return this;
}
*/
org.sonar.batch.protocol.output.BatchReport.IssueOrBuilder getIssueOrBuilder(
int index);
-
- /**
- * <code>optional string component_uuid = 3;</code>
- *
- * <pre>
- * Temporary field for issues on deleted components
- * </pre>
- */
- boolean hasComponentUuid();
- /**
- * <code>optional string component_uuid = 3;</code>
- *
- * <pre>
- * Temporary field for issues on deleted components
- * </pre>
- */
- java.lang.String getComponentUuid();
- /**
- * <code>optional string component_uuid = 3;</code>
- *
- * <pre>
- * Temporary field for issues on deleted components
- * </pre>
- */
- com.google.protobuf.ByteString
- getComponentUuidBytes();
}
/**
* Protobuf type {@code Issues}
issue_.add(input.readMessage(org.sonar.batch.protocol.output.BatchReport.Issue.PARSER, extensionRegistry));
break;
}
- case 26: {
- com.google.protobuf.ByteString bs = input.readBytes();
- bitField0_ |= 0x00000002;
- componentUuid_ = bs;
- break;
- }
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
return issue_.get(index);
}
- public static final int COMPONENT_UUID_FIELD_NUMBER = 3;
- private java.lang.Object componentUuid_;
- /**
- * <code>optional string component_uuid = 3;</code>
- *
- * <pre>
- * Temporary field for issues on deleted components
- * </pre>
- */
- public boolean hasComponentUuid() {
- return ((bitField0_ & 0x00000002) == 0x00000002);
- }
- /**
- * <code>optional string component_uuid = 3;</code>
- *
- * <pre>
- * Temporary field for issues on deleted components
- * </pre>
- */
- public java.lang.String getComponentUuid() {
- java.lang.Object ref = componentUuid_;
- if (ref instanceof java.lang.String) {
- return (java.lang.String) ref;
- } else {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- componentUuid_ = s;
- }
- return s;
- }
- }
- /**
- * <code>optional string component_uuid = 3;</code>
- *
- * <pre>
- * Temporary field for issues on deleted components
- * </pre>
- */
- public com.google.protobuf.ByteString
- getComponentUuidBytes() {
- java.lang.Object ref = componentUuid_;
- if (ref instanceof java.lang.String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- componentUuid_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
- }
-
private void initFields() {
componentRef_ = 0;
issue_ = java.util.Collections.emptyList();
- componentUuid_ = "";
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
for (int i = 0; i < issue_.size(); i++) {
output.writeMessage(2, issue_.get(i));
}
- if (((bitField0_ & 0x00000002) == 0x00000002)) {
- output.writeBytes(3, getComponentUuidBytes());
- }
getUnknownFields().writeTo(output);
}
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(2, issue_.get(i));
}
- if (((bitField0_ & 0x00000002) == 0x00000002)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(3, getComponentUuidBytes());
- }
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
} else {
issueBuilder_.clear();
}
- componentUuid_ = "";
- bitField0_ = (bitField0_ & ~0x00000004);
return this;
}
} else {
result.issue_ = issueBuilder_.build();
}
- if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
- to_bitField0_ |= 0x00000002;
- }
- result.componentUuid_ = componentUuid_;
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
}
}
}
- if (other.hasComponentUuid()) {
- bitField0_ |= 0x00000004;
- componentUuid_ = other.componentUuid_;
- onChanged();
- }
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
return issueBuilder_;
}
- private java.lang.Object componentUuid_ = "";
- /**
- * <code>optional string component_uuid = 3;</code>
- *
- * <pre>
- * Temporary field for issues on deleted components
- * </pre>
- */
- public boolean hasComponentUuid() {
- return ((bitField0_ & 0x00000004) == 0x00000004);
- }
- /**
- * <code>optional string component_uuid = 3;</code>
- *
- * <pre>
- * Temporary field for issues on deleted components
- * </pre>
- */
- public java.lang.String getComponentUuid() {
- java.lang.Object ref = componentUuid_;
- if (!(ref instanceof java.lang.String)) {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- componentUuid_ = s;
- }
- return s;
- } else {
- return (java.lang.String) ref;
- }
- }
- /**
- * <code>optional string component_uuid = 3;</code>
- *
- * <pre>
- * Temporary field for issues on deleted components
- * </pre>
- */
- public com.google.protobuf.ByteString
- getComponentUuidBytes() {
- java.lang.Object ref = componentUuid_;
- if (ref instanceof String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- componentUuid_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
- }
- /**
- * <code>optional string component_uuid = 3;</code>
- *
- * <pre>
- * Temporary field for issues on deleted components
- * </pre>
- */
- public Builder setComponentUuid(
- java.lang.String value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000004;
- componentUuid_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional string component_uuid = 3;</code>
- *
- * <pre>
- * Temporary field for issues on deleted components
- * </pre>
- */
- public Builder clearComponentUuid() {
- bitField0_ = (bitField0_ & ~0x00000004);
- componentUuid_ = getDefaultInstance().getComponentUuid();
- onChanged();
- return this;
- }
- /**
- * <code>optional string component_uuid = 3;</code>
- *
- * <pre>
- * Temporary field for issues on deleted components
- * </pre>
- */
- public Builder setComponentUuidBytes(
- com.google.protobuf.ByteString value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000004;
- componentUuid_ = value;
- onChanged();
- return this;
- }
-
// @@protoc_insertion_point(builder_scope:Issues)
}
descriptor;
static {
java.lang.String[] descriptorData = {
- "\n\022batch_report.proto\032\017constants.proto\"\204\001" +
- "\n\010Metadata\022\025\n\ranalysis_date\030\001 \001(\003\022\023\n\013pro" +
- "ject_key\030\002 \001(\t\022\016\n\006branch\030\003 \001(\t\022\032\n\022root_c" +
- "omponent_ref\030\004 \001(\005\022 \n\030deleted_components" +
- "_count\030\005 \001(\005\"?\n\rComponentLink\022 \n\004type\030\001 " +
- "\001(\0162\022.ComponentLinkType\022\014\n\004href\030\002 \001(\t\"\354\001" +
- "\n\tComponent\022\013\n\003ref\030\001 \001(\005\022\014\n\004path\030\002 \001(\t\022\014" +
- "\n\004name\030\003 \001(\t\022\034\n\004type\030\004 \001(\0162\016.ComponentTy" +
- "pe\022\017\n\007is_test\030\005 \001(\010\022\020\n\010language\030\006 \001(\t\022\025\n" +
- "\tchild_ref\030\007 \003(\005B\002\020\001\022\034\n\004link\030\010 \003(\0132\016.Com",
- "ponentLink\022\017\n\007version\030\t \001(\t\022\013\n\003key\030\n \001(\t" +
- "\022\r\n\005lines\030\013 \001(\005\022\023\n\013description\030\014 \001(\t\"\261\003\n" +
- "\007Measure\022%\n\nvalue_type\030\001 \001(\0162\021.MeasureVa" +
- "lueType\022\025\n\rboolean_value\030\002 \001(\010\022\021\n\tint_va" +
- "lue\030\003 \001(\005\022\022\n\nlong_value\030\004 \001(\003\022\024\n\014double_" +
- "value\030\005 \001(\001\022\024\n\014string_value\030\006 \001(\t\022\022\n\nmet" +
- "ric_key\030\007 \001(\t\022\023\n\013description\030\t \001(\t\022\020\n\010ru" +
- "le_key\030\n \001(\t\022\024\n\014alert_status\030\014 \001(\t\022\022\n\nal" +
- "ert_text\030\r \001(\t\022\031\n\021variation_value_1\030\016 \001(" +
- "\001\022\031\n\021variation_value_2\030\017 \001(\001\022\031\n\021variatio",
- "n_value_3\030\020 \001(\001\022\031\n\021variation_value_4\030\021 \001" +
- "(\001\022\031\n\021variation_value_5\030\022 \001(\001\022\026\n\016charact" +
- "eric_id\030\023 \001(\005\022\021\n\tperson_id\030\024 \001(\005\"<\n\010Meas" +
- "ures\022\025\n\rcomponent_ref\030\001 \001(\005\022\031\n\007measure\030\002" +
- " \003(\0132\010.Measure\"\231\004\n\005Issue\022\027\n\017rule_reposit" +
- "ory\030\001 \001(\t\022\020\n\010rule_key\030\002 \001(\t\022\014\n\004line\030\003 \001(" +
- "\005\022\013\n\003msg\030\004 \001(\t\022\033\n\010severity\030\005 \001(\0162\t.Sever" +
- "ity\022\013\n\003tag\030\006 \003(\t\022\025\n\reffort_to_fix\030\007 \001(\001\022" +
- "\016\n\006is_new\030\010 \001(\010\022\014\n\004uuid\030\t \001(\t\022\027\n\017debt_in" +
- "_minutes\030\n \001(\003\022\022\n\nresolution\030\013 \001(\t\022\016\n\006st",
- "atus\030\014 \001(\t\022\020\n\010checksum\030\r \001(\t\022\027\n\017manual_s" +
- "everity\030\016 \001(\010\022\020\n\010reporter\030\017 \001(\t\022\020\n\010assig" +
- "nee\030\020 \001(\t\022\027\n\017action_plan_key\030\021 \001(\t\022\022\n\nat" +
- "tributes\030\022 \001(\t\022\024\n\014author_login\030\023 \001(\t\022\025\n\r" +
- "creation_date\030\024 \001(\003\022\022\n\nclose_date\030\025 \001(\003\022" +
- "\023\n\013update_date\030\026 \001(\003\022\023\n\013selected_at\030\027 \001(" +
- "\003\022\023\n\013diff_fields\030\030 \001(\t\022\022\n\nis_changed\030\031 \001" +
- "(\010\022\036\n\026must_send_notification\030\032 \001(\010\"N\n\006Is" +
- "sues\022\025\n\rcomponent_ref\030\001 \001(\005\022\025\n\005issue\030\002 \003" +
- "(\0132\006.Issue\022\026\n\016component_uuid\030\003 \001(\t\"\254\001\n\nC",
- "hangesets\022\025\n\rcomponent_ref\030\001 \001(\005\022(\n\tchan" +
- "geset\030\002 \003(\0132\025.Changesets.Changeset\022 \n\024ch" +
- "angesetIndexByLine\030\003 \003(\005B\002\020\001\032;\n\tChangese" +
- "t\022\020\n\010revision\030\001 \001(\t\022\016\n\006author\030\002 \001(\t\022\014\n\004d" +
- "ate\030\003 \001(\003\"R\n\tDuplicate\022\026\n\016other_file_ref" +
- "\030\001 \001(\005\022\025\n\005range\030\002 \001(\0132\006.Range\022\026\n\016other_f" +
- "ile_key\030\003 \001(\t\"M\n\013Duplication\022\037\n\017origin_p" +
- "osition\030\001 \001(\0132\006.Range\022\035\n\tduplicate\030\002 \003(\013" +
- "2\n.Duplicate\"H\n\014Duplications\022\025\n\rcomponen" +
- "t_ref\030\001 \001(\005\022!\n\013duplication\030\002 \003(\0132\014.Dupli",
- "cation\"W\n\005Range\022\022\n\nstart_line\030\001 \001(\005\022\020\n\010e" +
- "nd_line\030\002 \001(\005\022\024\n\014start_offset\030\003 \001(\005\022\022\n\ne" +
- "nd_offset\030\004 \001(\005\"~\n\007Symbols\022\020\n\010file_ref\030\001" +
- " \001(\005\022\037\n\006symbol\030\002 \003(\0132\017.Symbols.Symbol\032@\n" +
- "\006Symbol\022\033\n\013declaration\030\001 \001(\0132\006.Range\022\031\n\t" +
- "reference\030\002 \003(\0132\006.Range\"\260\001\n\010Coverage\022\014\n\004" +
- "line\030\001 \001(\005\022\022\n\nconditions\030\002 \001(\005\022\017\n\007ut_hit" +
- "s\030\003 \001(\010\022\017\n\007it_hits\030\004 \001(\010\022\035\n\025ut_covered_c" +
- "onditions\030\005 \001(\005\022\035\n\025it_covered_conditions" +
- "\030\006 \001(\005\022\"\n\032overall_covered_conditions\030\007 \001",
- "(\005\"L\n\022SyntaxHighlighting\022\025\n\005range\030\001 \001(\0132" +
- "\006.Range\022\037\n\004type\030\002 \001(\0162\021.HighlightingType" +
- "\"j\n\004Test\022\014\n\004name\030\001 \001(\t\022\033\n\006status\030\002 \001(\0162\013" +
- ".TestStatus\022\026\n\016duration_in_ms\030\003 \001(\003\022\022\n\ns" +
- "tacktrace\030\004 \001(\t\022\013\n\003msg\030\005 \001(\t\"\221\001\n\016Coverag" +
- "eDetail\022\021\n\ttest_name\030\001 \001(\t\0221\n\014covered_fi" +
- "le\030\002 \003(\0132\033.CoverageDetail.CoveredFile\0329\n" +
- "\013CoveredFile\022\020\n\010file_ref\030\001 \001(\005\022\030\n\014covere" +
- "d_line\030\002 \003(\005B\002\020\001B#\n\037org.sonar.batch.prot" +
- "ocol.outputH\001"
+ "\n\022batch_report.proto\032\017constants.proto\"b\n" +
+ "\010Metadata\022\025\n\ranalysis_date\030\001 \001(\003\022\023\n\013proj" +
+ "ect_key\030\002 \001(\t\022\016\n\006branch\030\003 \001(\t\022\032\n\022root_co" +
+ "mponent_ref\030\004 \001(\005\"?\n\rComponentLink\022 \n\004ty" +
+ "pe\030\001 \001(\0162\022.ComponentLinkType\022\014\n\004href\030\002 \001" +
+ "(\t\"\354\001\n\tComponent\022\013\n\003ref\030\001 \001(\005\022\014\n\004path\030\002 " +
+ "\001(\t\022\014\n\004name\030\003 \001(\t\022\034\n\004type\030\004 \001(\0162\016.Compon" +
+ "entType\022\017\n\007is_test\030\005 \001(\010\022\020\n\010language\030\006 \001" +
+ "(\t\022\025\n\tchild_ref\030\007 \003(\005B\002\020\001\022\034\n\004link\030\010 \003(\0132" +
+ "\016.ComponentLink\022\017\n\007version\030\t \001(\t\022\013\n\003key\030",
+ "\n \001(\t\022\r\n\005lines\030\013 \001(\005\022\023\n\013description\030\014 \001(" +
+ "\t\"\261\003\n\007Measure\022%\n\nvalue_type\030\001 \001(\0162\021.Meas" +
+ "ureValueType\022\025\n\rboolean_value\030\002 \001(\010\022\021\n\ti" +
+ "nt_value\030\003 \001(\005\022\022\n\nlong_value\030\004 \001(\003\022\024\n\014do" +
+ "uble_value\030\005 \001(\001\022\024\n\014string_value\030\006 \001(\t\022\022" +
+ "\n\nmetric_key\030\007 \001(\t\022\023\n\013description\030\t \001(\t\022" +
+ "\020\n\010rule_key\030\n \001(\t\022\024\n\014alert_status\030\014 \001(\t\022" +
+ "\022\n\nalert_text\030\r \001(\t\022\031\n\021variation_value_1" +
+ "\030\016 \001(\001\022\031\n\021variation_value_2\030\017 \001(\001\022\031\n\021var" +
+ "iation_value_3\030\020 \001(\001\022\031\n\021variation_value_",
+ "4\030\021 \001(\001\022\031\n\021variation_value_5\030\022 \001(\001\022\026\n\016ch" +
+ "aracteric_id\030\023 \001(\005\022\021\n\tperson_id\030\024 \001(\005\"<\n" +
+ "\010Measures\022\025\n\rcomponent_ref\030\001 \001(\005\022\031\n\007meas" +
+ "ure\030\002 \003(\0132\010.Measure\"\273\001\n\005Issue\022\027\n\017rule_re" +
+ "pository\030\001 \001(\t\022\020\n\010rule_key\030\002 \001(\t\022\014\n\004line" +
+ "\030\003 \001(\005\022\013\n\003msg\030\004 \001(\t\022\033\n\010severity\030\005 \001(\0162\t." +
+ "Severity\022\013\n\003tag\030\006 \003(\t\022\025\n\reffort_to_fix\030\007" +
+ " \001(\001\022\022\n\nattributes\030\010 \001(\t\022\027\n\017debt_in_minu" +
+ "tes\030\t \001(\003\"6\n\006Issues\022\025\n\rcomponent_ref\030\001 \001" +
+ "(\005\022\025\n\005issue\030\002 \003(\0132\006.Issue\"\254\001\n\nChangesets",
+ "\022\025\n\rcomponent_ref\030\001 \001(\005\022(\n\tchangeset\030\002 \003" +
+ "(\0132\025.Changesets.Changeset\022 \n\024changesetIn" +
+ "dexByLine\030\003 \003(\005B\002\020\001\032;\n\tChangeset\022\020\n\010revi" +
+ "sion\030\001 \001(\t\022\016\n\006author\030\002 \001(\t\022\014\n\004date\030\003 \001(\003" +
+ "\"R\n\tDuplicate\022\026\n\016other_file_ref\030\001 \001(\005\022\025\n" +
+ "\005range\030\002 \001(\0132\006.Range\022\026\n\016other_file_key\030\003" +
+ " \001(\t\"M\n\013Duplication\022\037\n\017origin_position\030\001" +
+ " \001(\0132\006.Range\022\035\n\tduplicate\030\002 \003(\0132\n.Duplic" +
+ "ate\"H\n\014Duplications\022\025\n\rcomponent_ref\030\001 \001" +
+ "(\005\022!\n\013duplication\030\002 \003(\0132\014.Duplication\"W\n",
+ "\005Range\022\022\n\nstart_line\030\001 \001(\005\022\020\n\010end_line\030\002" +
+ " \001(\005\022\024\n\014start_offset\030\003 \001(\005\022\022\n\nend_offset" +
+ "\030\004 \001(\005\"~\n\007Symbols\022\020\n\010file_ref\030\001 \001(\005\022\037\n\006s" +
+ "ymbol\030\002 \003(\0132\017.Symbols.Symbol\032@\n\006Symbol\022\033" +
+ "\n\013declaration\030\001 \001(\0132\006.Range\022\031\n\treference" +
+ "\030\002 \003(\0132\006.Range\"\260\001\n\010Coverage\022\014\n\004line\030\001 \001(" +
+ "\005\022\022\n\nconditions\030\002 \001(\005\022\017\n\007ut_hits\030\003 \001(\010\022\017" +
+ "\n\007it_hits\030\004 \001(\010\022\035\n\025ut_covered_conditions" +
+ "\030\005 \001(\005\022\035\n\025it_covered_conditions\030\006 \001(\005\022\"\n" +
+ "\032overall_covered_conditions\030\007 \001(\005\"L\n\022Syn",
+ "taxHighlighting\022\025\n\005range\030\001 \001(\0132\006.Range\022\037" +
+ "\n\004type\030\002 \001(\0162\021.HighlightingType\"j\n\004Test\022" +
+ "\014\n\004name\030\001 \001(\t\022\033\n\006status\030\002 \001(\0162\013.TestStat" +
+ "us\022\026\n\016duration_in_ms\030\003 \001(\003\022\022\n\nstacktrace" +
+ "\030\004 \001(\t\022\013\n\003msg\030\005 \001(\t\"\221\001\n\016CoverageDetail\022\021" +
+ "\n\ttest_name\030\001 \001(\t\0221\n\014covered_file\030\002 \003(\0132" +
+ "\033.CoverageDetail.CoveredFile\0329\n\013CoveredF" +
+ "ile\022\020\n\010file_ref\030\001 \001(\005\022\030\n\014covered_line\030\002 " +
+ "\003(\005B\002\020\001B#\n\037org.sonar.batch.protocol.outp" +
+ "utH\001"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
internal_static_Metadata_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_Metadata_descriptor,
- new java.lang.String[] { "AnalysisDate", "ProjectKey", "Branch", "RootComponentRef", "DeletedComponentsCount", });
+ new java.lang.String[] { "AnalysisDate", "ProjectKey", "Branch", "RootComponentRef", });
internal_static_ComponentLink_descriptor =
getDescriptor().getMessageTypes().get(1);
internal_static_ComponentLink_fieldAccessorTable = new
internal_static_Issue_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_Issue_descriptor,
- new java.lang.String[] { "RuleRepository", "RuleKey", "Line", "Msg", "Severity", "Tag", "EffortToFix", "IsNew", "Uuid", "DebtInMinutes", "Resolution", "Status", "Checksum", "ManualSeverity", "Reporter", "Assignee", "ActionPlanKey", "Attributes", "AuthorLogin", "CreationDate", "CloseDate", "UpdateDate", "SelectedAt", "DiffFields", "IsChanged", "MustSendNotification", });
+ new java.lang.String[] { "RuleRepository", "RuleKey", "Line", "Msg", "Severity", "Tag", "EffortToFix", "Attributes", "DebtInMinutes", });
internal_static_Issues_descriptor =
getDescriptor().getMessageTypes().get(6);
internal_static_Issues_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_Issues_descriptor,
- new java.lang.String[] { "ComponentRef", "Issue", "ComponentUuid", });
+ new java.lang.String[] { "ComponentRef", "Issue", });
internal_static_Changesets_descriptor =
getDescriptor().getMessageTypes().get(7);
internal_static_Changesets_fieldAccessorTable = new
return Collections.emptyList();
}
- public Issues readDeletedComponentIssues(int deletedComponentRef) {
- File file = fileStructure.fileFor(FileStructure.Domain.ISSUES_ON_DELETED, deletedComponentRef);
- if (!doesFileExists(file)) {
- throw new IllegalStateException("Unable to find report for deleted component #" + deletedComponentRef);
- }
- // all the issues are loaded in memory
- return ProtobufUtil.readFile(file, Issues.PARSER);
- }
-
public List<BatchReport.Duplication> readComponentDuplications(int componentRef) {
File file = fileStructure.fileFor(FileStructure.Domain.DUPLICATIONS, componentRef);
if (doesFileExists(file)) {
return file;
}
- /**
- * Issues on components which have been deleted are stored in another location.
- * Temporary hack, waiting for computation stack
- */
- public File writeDeletedComponentIssues(int componentRef, String componentUuid, Iterable<BatchReport.Issue> issues) {
- BatchReport.Issues.Builder issuesBuilder = BatchReport.Issues.newBuilder();
- issuesBuilder.setComponentRef(componentRef);
- issuesBuilder.setComponentUuid(componentUuid);
- issuesBuilder.addAllIssue(issues);
- File file = fileStructure.fileFor(FileStructure.Domain.ISSUES_ON_DELETED, componentRef);
- ProtobufUtil.writeToFile(issuesBuilder.build(), file);
- return file;
- }
-
public File writeComponentDuplications(int componentRef, Iterable<BatchReport.Duplication> duplications) {
BatchReport.Duplications.Builder builder = BatchReport.Duplications.newBuilder();
builder.setComponentRef(componentRef);
optional string project_key = 2;
optional string branch = 3;
optional int32 root_component_ref = 4;
-
- // temporary fields used during development of computation stack
- optional int32 deleted_components_count = 5;
}
message ComponentLink {
optional string msg = 4;
optional Severity severity = 5;
repeated string tag = 6;
-
- // temporary fields during development of computation stack
optional double effort_to_fix = 7;
- optional bool is_new = 8;
- optional string uuid = 9;
- optional int64 debt_in_minutes = 10;
- optional string resolution = 11;
- optional string status = 12;
- optional string checksum = 13;
- optional bool manual_severity = 14;
- optional string reporter = 15;
- optional string assignee = 16;
- optional string action_plan_key = 17;
- optional string attributes = 18;
- optional string author_login = 19;
- optional int64 creation_date = 20;
- optional int64 close_date = 21;
- optional int64 update_date = 22;
- optional int64 selected_at = 23;
- optional string diff_fields = 24;
- optional bool is_changed = 25;
- optional bool must_send_notification = 26;
+ optional string attributes = 8;
+
+ // TODO should it be moved to compute engine?
+ optional int64 debt_in_minutes = 9;
}
message Issues {
optional int32 component_ref = 1;
repeated Issue issue = 2;
-
- // Temporary field for issues on deleted components
- optional string component_uuid = 3;
}
message Changesets {
BatchReport.Metadata.Builder metadata = BatchReport.Metadata.newBuilder()
.setAnalysisDate(15000000L)
.setProjectKey("PROJECT_A")
- .setRootComponentRef(1)
- .setDeletedComponentsCount(10);
+ .setRootComponentRef(1);
writer.writeMetadata(metadata.build());
BatchReport.Metadata readMetadata = sut.readMetadata();
assertThat(readMetadata.getAnalysisDate()).isEqualTo(15000000L);
assertThat(readMetadata.getProjectKey()).isEqualTo("PROJECT_A");
- assertThat(readMetadata.getDeletedComponentsCount()).isEqualTo(10);
assertThat(readMetadata.getRootComponentRef()).isEqualTo(1);
}
public void read_issues() {
BatchReportWriter writer = new BatchReportWriter(dir);
BatchReport.Issue issue = BatchReport.Issue.newBuilder()
- .setUuid("ISSUE_A")
.setLine(50)
.build();
writer.writeComponentIssues(1, Arrays.asList(issue));
- writer.writeDeletedComponentIssues(1, "compUuid", Arrays.asList(issue));
assertThat(sut.readComponentIssues(1)).hasSize(1);
assertThat(sut.readComponentIssues(200)).isEmpty();
-
- BatchReport.Issues deletedComponentIssues = sut.readDeletedComponentIssues(1);
- assertThat(deletedComponentIssues.getComponentUuid()).isEqualTo("compUuid");
- assertThat(deletedComponentIssues.getIssueList()).hasSize(1);
- }
-
- @Test(expected = IllegalStateException.class)
- public void fail_if_missing_file_on_deleted_component() {
- sut.readDeletedComponentIssues(UNKNOWN_COMPONENT_REF);
}
@Test
// write data
BatchReport.Issue issue = BatchReport.Issue.newBuilder()
- .setUuid("ISSUE_A")
.setLine(50)
.setMsg("the message")
.build();
assertThat(file).exists().isFile();
BatchReport.Issues read = ProtobufUtil.readFile(file, BatchReport.Issues.PARSER);
assertThat(read.getComponentRef()).isEqualTo(1);
- assertThat(read.hasComponentUuid()).isFalse();
- assertThat(read.getIssueCount()).isEqualTo(1);
- }
-
- @Test
- public void write_issues_of_deleted_component() {
- // no data yet
- assertThat(sut.hasComponentData(FileStructure.Domain.ISSUES_ON_DELETED, 1)).isFalse();
-
- // write data
- BatchReport.Issue issue = BatchReport.Issue.newBuilder()
- .setUuid("ISSUE_A")
- .setLine(50)
- .setMsg("the message")
- .build();
-
- sut.writeDeletedComponentIssues(1, "componentUuid", Arrays.asList(issue));
-
- assertThat(sut.hasComponentData(FileStructure.Domain.ISSUES_ON_DELETED, 1)).isTrue();
- File file = sut.getFileStructure().fileFor(FileStructure.Domain.ISSUES_ON_DELETED, 1);
- assertThat(file).exists().isFile();
- BatchReport.Issues read = ProtobufUtil.readFile(file, BatchReport.Issues.PARSER);
- assertThat(read.getComponentRef()).isEqualTo(1);
- assertThat(read.getComponentUuid()).isEqualTo("componentUuid");
assertThat(read.getIssueCount()).isEqualTo(1);
}
import org.sonar.batch.debt.DebtDecorator;
import org.sonar.batch.debt.IssueChangelogDebtCalculator;
import org.sonar.batch.debt.NewDebtDecorator;
-import org.sonar.batch.issue.tracking.InitialOpenIssuesSensor;
-import org.sonar.batch.issue.tracking.IssueHandlers;
import org.sonar.batch.issue.tracking.IssueTracking;
-import org.sonar.batch.issue.tracking.IssueTrackingDecorator;
import org.sonar.batch.language.LanguageDistributionDecorator;
import org.sonar.batch.scan.report.ConsoleReport;
import org.sonar.batch.scan.report.HtmlReport;
DebtDecorator.class,
NewDebtDecorator.class,
- // Issue tracking
- IssueTrackingDecorator.class,
- IssueHandlers.class,
- InitialOpenIssuesSensor.class,
-
// to be moved to compute engine
UnitTestDecorator.class,
LineCoverageDecorator.class,
import org.sonar.api.component.ResourcePerspectives;
import org.sonar.api.issue.Issuable;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilters;
import org.apache.commons.lang.time.DateUtils;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.core.issue.IssueUpdater;
import static com.google.common.collect.Lists.newArrayList;
+++ /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.
- */
-package org.sonar.batch.index;
-
-import org.sonar.api.batch.BatchSide;
-
-@BatchSide
-public interface ScanPersister {
-
- void persist();
-
-}
import java.util.List;
import org.sonar.api.issue.Issuable;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.Project;
import org.sonar.batch.index.BatchComponent;
import org.sonar.core.issue.DefaultIssueBuilder;
import com.google.common.collect.Iterables;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.ProjectIssues;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import javax.annotation.Nullable;
package org.sonar.batch.issue;
import org.sonar.api.batch.BatchSide;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.batch.index.Cache;
import org.sonar.batch.index.Caches;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.issue.batch.IssueFilter;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
@BatchSide
public class IssueFilters {
import org.sonar.api.batch.rule.Rule;
import org.sonar.api.batch.rule.Rules;
import org.sonar.api.batch.rule.internal.DefaultActiveRule;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.Project;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.Violation;
+++ /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.
- */
-package org.sonar.batch.issue.tracking;
-
-import java.util.Calendar;
-import java.util.Date;
-import org.apache.commons.lang.time.DateUtils;
-import org.apache.ibatis.session.ResultContext;
-import org.apache.ibatis.session.ResultHandler;
-import org.sonar.api.batch.RequiresDB;
-import org.sonar.api.batch.Sensor;
-import org.sonar.api.batch.SensorContext;
-import org.sonar.api.resources.Project;
-import org.sonar.core.issue.db.IssueChangeDao;
-import org.sonar.core.issue.db.IssueChangeDto;
-import org.sonar.core.issue.db.IssueDao;
-import org.sonar.core.issue.db.IssueDto;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceQuery;
-
-/**
- * Load all the issues referenced during the previous scan.
- */
-@RequiresDB
-public class InitialOpenIssuesSensor implements Sensor {
-
- private final InitialOpenIssuesStack initialOpenIssuesStack;
- private final IssueDao issueDao;
- private final IssueChangeDao issueChangeDao;
- private final ResourceDao resourceDao;
-
- public InitialOpenIssuesSensor(InitialOpenIssuesStack initialOpenIssuesStack, IssueDao issueDao, IssueChangeDao issueChangeDao, ResourceDao resourceDao) {
- this.initialOpenIssuesStack = initialOpenIssuesStack;
- this.issueDao = issueDao;
- this.issueChangeDao = issueChangeDao;
- this.resourceDao = resourceDao;
- }
-
- @Override
- public boolean shouldExecuteOnProject(Project project) {
- return true;
- }
-
- @Override
- public void analyse(Project project, SensorContext context) {
- ResourceDto module = resourceDao.getResource(ResourceQuery.create().setKey(project.getEffectiveKey()));
- if (module != null) {
- long moduleId = module.getId();
- // Adding one second is a hack for resolving conflicts with concurrent user
- // changes during issue persistence
- final Date now = DateUtils.addSeconds(DateUtils.truncate(new Date(), Calendar.MILLISECOND), 1);
- issueDao.selectNonClosedIssuesByModule(moduleId, new ResultHandler() {
- @Override
- public void handleResult(ResultContext rc) {
- IssueDto dto = (IssueDto) rc.getResultObject();
- dto.setSelectedAt(now.getTime());
- initialOpenIssuesStack.addIssue(dto);
- }
- });
-
- issueChangeDao.selectChangelogOnNonClosedIssuesByModuleAndType(moduleId, new ResultHandler() {
- @Override
- public void handleResult(ResultContext rc) {
- IssueChangeDto dto = (IssueChangeDto) rc.getResultObject();
- initialOpenIssuesStack.addChangelog(dto);
- }
- });
- }
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName();
- }
-}
+++ /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.
- */
-
-package org.sonar.batch.issue.tracking;
-
-import org.sonar.api.batch.BatchSide;
-import org.sonar.api.batch.InstantiationStrategy;
-import org.sonar.batch.index.Cache;
-import org.sonar.batch.index.Caches;
-import org.sonar.core.issue.db.IssueChangeDto;
-import org.sonar.core.issue.db.IssueDto;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import static com.google.common.collect.Lists.newArrayList;
-
-@BatchSide
-@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
-public class InitialOpenIssuesStack {
-
- private final Cache<IssueDto> issuesCache;
- private final Cache<ArrayList<IssueChangeDto>> issuesChangelogCache;
-
- public InitialOpenIssuesStack(Caches caches) {
- issuesCache = caches.createCache("last-open-issues");
- issuesChangelogCache = caches.createCache("issues-changelog");
- }
-
- public InitialOpenIssuesStack addIssue(IssueDto issueDto) {
- issuesCache.put(issueDto.getComponentKey(), issueDto.getKee(), issueDto);
- return this;
- }
-
- public List<ServerIssue> selectAndRemoveIssues(String componentKey) {
- Iterable<IssueDto> issues = issuesCache.values(componentKey);
- List<ServerIssue> result = newArrayList();
- for (IssueDto issue : issues) {
- result.add(new ServerIssueFromDb(issue));
- }
- issuesCache.clear(componentKey);
- return result;
- }
-
- public Iterable<IssueDto> selectAllIssues() {
- return issuesCache.values();
- }
-
- public InitialOpenIssuesStack addChangelog(IssueChangeDto issueChangeDto) {
- List<IssueChangeDto> changeDtos = issuesChangelogCache.get(issueChangeDto.getIssueKey());
- if (changeDtos == null) {
- changeDtos = newArrayList();
- }
- changeDtos.add(issueChangeDto);
- issuesChangelogCache.put(issueChangeDto.getIssueKey(), newArrayList(changeDtos));
- return this;
- }
-
- public List<IssueChangeDto> selectChangelog(String issueKey) {
- List<IssueChangeDto> changeDtos = issuesChangelogCache.get(issueKey);
- return changeDtos != null ? changeDtos : Collections.<IssueChangeDto>emptyList();
- }
-
- public void clear() {
- issuesCache.clear();
- issuesChangelogCache.clear();
- }
-}
+++ /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.
- */
-package org.sonar.batch.issue.tracking;
-
-import org.sonar.api.batch.BatchSide;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueHandler;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.api.user.User;
-import org.sonar.core.issue.IssueUpdater;
-import org.sonar.core.user.DefaultUser;
-
-import javax.annotation.Nullable;
-
-@BatchSide
-public class IssueHandlers {
- private final IssueHandler[] handlers;
- private final DefaultContext context;
-
- public IssueHandlers(IssueUpdater updater, IssueHandler[] handlers) {
- this.handlers = handlers;
- this.context = new DefaultContext(updater);
- }
-
- public IssueHandlers(IssueUpdater updater) {
- this(updater, new IssueHandler[0]);
- }
-
- public void execute(DefaultIssue issue, IssueChangeContext changeContext) {
- context.reset(issue, changeContext);
- for (IssueHandler handler : handlers) {
- handler.onIssue(context);
- }
- }
-
- static class DefaultContext implements IssueHandler.Context {
- private final IssueUpdater updater;
- private DefaultIssue issue;
- private IssueChangeContext changeContext;
-
- private DefaultContext(IssueUpdater updater) {
- this.updater = updater;
- }
-
- private void reset(DefaultIssue i, IssueChangeContext changeContext) {
- this.issue = i;
- this.changeContext = changeContext;
- }
-
- @Override
- public Issue issue() {
- return issue;
- }
-
- @Override
- public boolean isNew() {
- return issue.isNew();
- }
-
- @Override
- public boolean isEndOfLife() {
- return issue.isEndOfLife();
- }
-
- @Override
- public IssueHandler.Context setLine(@Nullable Integer line) {
- updater.setLine(issue, line);
- return this;
- }
-
- @Override
- public IssueHandler.Context setMessage(@Nullable String s) {
- updater.setMessage(issue, s, changeContext);
- return this;
- }
-
- @Override
- public IssueHandler.Context setSeverity(String severity) {
- updater.setSeverity(issue, severity, changeContext);
- return this;
- }
-
- @Override
- public IssueHandler.Context setAuthorLogin(@Nullable String login) {
- updater.setAuthorLogin(issue, login, changeContext);
- return this;
- }
-
- @Override
- public IssueHandler.Context setEffortToFix(@Nullable Double d) {
- updater.setEffortToFix(issue, d, changeContext);
- return this;
- }
-
- @Override
- public IssueHandler.Context setAttribute(String key, @Nullable String value) {
- throw new UnsupportedOperationException("TODO");
- }
-
- @Override
- public IssueHandler.Context assign(@Nullable String assignee) {
- User user = null;
- if (assignee != null) {
- user = new DefaultUser().setLogin(assignee).setName(assignee);
- }
- updater.assign(issue, user, changeContext);
- return this;
- }
-
- @Override
- public IssueHandler.Context assign(@Nullable User user) {
- updater.assign(issue, user, changeContext);
- return this;
- }
-
- @Override
- public IssueHandler.Context addComment(String text) {
- updater.addComment(issue, text, changeContext);
- return this;
- }
- }
-
-}
import com.google.common.collect.Multimap;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.batch.InstantiationStrategy;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import javax.annotation.Nullable;
+++ /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.
- */
-package org.sonar.batch.issue.tracking;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorBarriers;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependedUpon;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.batch.RequiresDB;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.component.ResourcePerspectives;
-import org.sonar.api.issue.Issuable;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-import org.sonar.api.rules.ActiveRule;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
-import org.sonar.api.utils.Duration;
-import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.batch.issue.IssueCache;
-import org.sonar.batch.scan.filesystem.InputPathCache;
-import org.sonar.core.issue.IssueUpdater;
-import org.sonar.core.issue.db.IssueChangeDto;
-import org.sonar.core.issue.db.IssueDto;
-import org.sonar.core.issue.workflow.IssueWorkflow;
-
-import java.util.Collection;
-
-@DependsUpon(DecoratorBarriers.ISSUES_ADDED)
-@DependedUpon(DecoratorBarriers.ISSUES_TRACKED)
-@RequiresDB
-public class IssueTrackingDecorator implements Decorator {
-
- private static final Logger LOG = LoggerFactory.getLogger(IssueTrackingDecorator.class);
-
- private final IssueCache issueCache;
- private final InitialOpenIssuesStack initialOpenIssues;
- private final IssueTracking tracking;
- private final ServerLineHashesLoader lastLineHashes;
- private final IssueHandlers handlers;
- private final IssueWorkflow workflow;
- private final IssueUpdater updater;
- private final IssueChangeContext changeContext;
- private final ResourcePerspectives perspectives;
- private final RulesProfile rulesProfile;
- private final RuleFinder ruleFinder;
- private final InputPathCache inputPathCache;
- private final Project project;
-
- public IssueTrackingDecorator(IssueCache issueCache, InitialOpenIssuesStack initialOpenIssues, IssueTracking tracking,
- ServerLineHashesLoader lastLineHashes,
- IssueHandlers handlers, IssueWorkflow workflow,
- IssueUpdater updater,
- Project project,
- ResourcePerspectives perspectives,
- RulesProfile rulesProfile,
- RuleFinder ruleFinder, InputPathCache inputPathCache) {
- this.issueCache = issueCache;
- this.initialOpenIssues = initialOpenIssues;
- this.tracking = tracking;
- this.lastLineHashes = lastLineHashes;
- this.handlers = handlers;
- this.workflow = workflow;
- this.updater = updater;
- this.project = project;
- this.inputPathCache = inputPathCache;
- this.changeContext = IssueChangeContext.createScan(project.getAnalysisDate());
- this.perspectives = perspectives;
- this.rulesProfile = rulesProfile;
- this.ruleFinder = ruleFinder;
- }
-
- @Override
- public boolean shouldExecuteOnProject(Project project) {
- return true;
- }
-
- @Override
- public void decorate(Resource resource, DecoratorContext context) {
- Issuable issuable = perspectives.as(Issuable.class, resource);
- if (issuable != null) {
- doDecorate(resource);
- }
- }
-
- @VisibleForTesting
- void doDecorate(Resource resource) {
- Collection<DefaultIssue> issues = Lists.newArrayList();
- for (Issue issue : issueCache.byComponent(resource.getEffectiveKey())) {
- issues.add((DefaultIssue) issue);
- }
- issueCache.clear(resource.getEffectiveKey());
- // issues = all the issues created by rule engines during this module scan and not excluded by filters
-
- // all the issues that are not closed in db before starting this module scan, including manual issues
- Collection<ServerIssue> dbOpenIssues = initialOpenIssues.selectAndRemoveIssues(resource.getEffectiveKey());
-
- SourceHashHolder sourceHashHolder = null;
- if (ResourceUtils.isFile(resource)) {
- File sonarFile = (File) resource;
- InputFile file = inputPathCache.getFile(project.getEffectiveKey(), sonarFile.getPath());
- if (file == null) {
- throw new IllegalStateException("File " + resource + " was not found in InputPath cache");
- }
- sourceHashHolder = new SourceHashHolder((DefaultInputFile) file, lastLineHashes);
- }
-
- IssueTrackingResult trackingResult = tracking.track(sourceHashHolder, dbOpenIssues, issues);
-
- // unmatched = issues that have been resolved + issues on disabled/removed rules + manual issues
- addUnmatched(trackingResult.unmatched(), sourceHashHolder, issues);
-
- mergeMatched(trackingResult);
-
- if (ResourceUtils.isProject(resource)) {
- // issues that relate to deleted components
- addIssuesOnDeletedComponents(issues);
- }
-
- for (DefaultIssue issue : issues) {
- workflow.doAutomaticTransition(issue, changeContext);
- handlers.execute(issue, changeContext);
- issueCache.put(issue);
- }
- }
-
- @VisibleForTesting
- protected void mergeMatched(IssueTrackingResult result) {
- for (DefaultIssue issue : result.matched()) {
- IssueDto ref = ((ServerIssueFromDb) result.matching(issue)).getDto();
-
- // invariant fields
- issue.setKey(ref.getKee());
- issue.setCreationDate(ref.getIssueCreationDate());
- issue.setUpdateDate(ref.getIssueUpdateDate());
- issue.setCloseDate(ref.getIssueCloseDate());
-
- // non-persisted fields
- issue.setNew(false);
- issue.setEndOfLife(false);
- issue.setOnDisabledRule(false);
- issue.setSelectedAt(ref.getSelectedAt());
-
- // fields to update with old values
- issue.setActionPlanKey(ref.getActionPlanKey());
- issue.setResolution(ref.getResolution());
- issue.setStatus(ref.getStatus());
- issue.setAssignee(ref.getAssignee());
- issue.setAuthorLogin(ref.getAuthorLogin());
- issue.setTags(ref.getTags());
-
- if (ref.getIssueAttributes() != null) {
- issue.setAttributes(KeyValueFormat.parse(ref.getIssueAttributes()));
- }
-
- // populate existing changelog
- Collection<IssueChangeDto> issueChangeDtos = initialOpenIssues.selectChangelog(issue.key());
- for (IssueChangeDto issueChangeDto : issueChangeDtos) {
- issue.addChange(issueChangeDto.toFieldDiffs());
- }
-
- // fields to update with current values
- if (ref.isManualSeverity()) {
- issue.setManualSeverity(true);
- issue.setSeverity(ref.getSeverity());
- } else {
- updater.setPastSeverity(issue, ref.getSeverity(), changeContext);
- }
- updater.setPastLine(issue, ref.getLine());
- updater.setPastMessage(issue, ref.getMessage(), changeContext);
- updater.setPastEffortToFix(issue, ref.getEffortToFix(), changeContext);
- Long debtInMinutes = ref.getDebt();
- Duration previousTechnicalDebt = debtInMinutes != null ? Duration.create(debtInMinutes) : null;
- updater.setPastTechnicalDebt(issue, previousTechnicalDebt, changeContext);
- updater.setPastProject(issue, ref.getProjectKey(), changeContext);
- }
- }
-
- private void addUnmatched(Collection<ServerIssue> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<DefaultIssue> issues) {
- for (ServerIssue unmatchedIssue : unmatchedIssues) {
- IssueDto unmatchedDto = ((ServerIssueFromDb) unmatchedIssue).getDto();
- DefaultIssue unmatched = unmatchedDto.toDefaultIssue();
- if (StringUtils.isNotBlank(unmatchedDto.getReporter()) && !Issue.STATUS_CLOSED.equals(unmatchedDto.getStatus())) {
- relocateManualIssue(unmatched, unmatchedDto, sourceHashHolder);
- }
- updateUnmatchedIssue(unmatched, false /* manual issues can be kept open */);
- issues.add(unmatched);
- }
- }
-
- private void addIssuesOnDeletedComponents(Collection<DefaultIssue> issues) {
- for (IssueDto deadDto : initialOpenIssues.selectAllIssues()) {
- DefaultIssue dead = deadDto.toDefaultIssue();
- updateUnmatchedIssue(dead, true);
- issues.add(dead);
- }
- initialOpenIssues.clear();
- }
-
- private void updateUnmatchedIssue(DefaultIssue issue, boolean forceEndOfLife) {
- issue.setNew(false);
-
- boolean manualIssue = !Strings.isNullOrEmpty(issue.reporter());
- Rule rule = ruleFinder.findByKey(issue.ruleKey());
- if (manualIssue) {
- // Manual rules are not declared in Quality profiles, so no need to check ActiveRule
- boolean isRemovedRule = rule == null || Rule.STATUS_REMOVED.equals(rule.getStatus());
- issue.setEndOfLife(forceEndOfLife || isRemovedRule);
- issue.setOnDisabledRule(isRemovedRule);
- } else {
- ActiveRule activeRule = rulesProfile.getActiveRule(issue.ruleKey().repository(), issue.ruleKey().rule());
- issue.setEndOfLife(true);
- issue.setOnDisabledRule(activeRule == null || rule == null || Rule.STATUS_REMOVED.equals(rule.getStatus()));
- }
- }
-
- private void relocateManualIssue(DefaultIssue newIssue, IssueDto oldIssue, SourceHashHolder sourceHashHolder) {
- LOG.debug("Trying to relocate manual issue {}", oldIssue.getKee());
-
- Integer previousLine = oldIssue.getLine();
- if (previousLine == null) {
- LOG.debug("Cannot relocate issue at resource level");
- return;
- }
-
- Collection<Integer> newLinesWithSameHash = sourceHashHolder.getNewLinesMatching(previousLine);
- LOG.debug("Found the following lines with same hash: {}", newLinesWithSameHash);
- if (newLinesWithSameHash.isEmpty()) {
- if (previousLine > sourceHashHolder.getHashedSource().length()) {
- LOG.debug("Old issue line {} is out of new source, closing and removing line number", previousLine);
- newIssue.setLine(null);
- updater.setStatus(newIssue, Issue.STATUS_CLOSED, changeContext);
- updater.setResolution(newIssue, Issue.RESOLUTION_REMOVED, changeContext);
- updater.setPastLine(newIssue, previousLine);
- updater.setPastMessage(newIssue, oldIssue.getMessage(), changeContext);
- updater.setPastEffortToFix(newIssue, oldIssue.getEffortToFix(), changeContext);
- }
- } else if (newLinesWithSameHash.size() == 1) {
- Integer newLine = newLinesWithSameHash.iterator().next();
- LOG.debug("Relocating issue to line {}", newLine);
-
- newIssue.setLine(newLine);
- updater.setPastLine(newIssue, previousLine);
- updater.setPastMessage(newIssue, oldIssue.getMessage(), changeContext);
- updater.setPastEffortToFix(newIssue, oldIssue.getEffortToFix(), changeContext);
- }
- }
-}
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import org.apache.commons.lang.StringUtils;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import javax.annotation.Nullable;
import org.sonar.api.batch.rule.ActiveRule;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.ResourceUtils;
import org.sonar.api.rule.RuleKey;
// non-persisted fields
issue.setNew(false);
- issue.setEndOfLife(false);
+ issue.setBeingClosed(false);
issue.setOnDisabledRule(false);
// fields to update with old values
boolean manualIssue = issue.ruleKey().isManual();
boolean isRemovedRule = activeRule == null;
if (manualIssue) {
- issue.setEndOfLife(forceEndOfLife || isRemovedRule);
+ issue.setBeingClosed(forceEndOfLife || isRemovedRule);
} else {
- issue.setEndOfLife(true);
+ issue.setBeingClosed(true);
}
issue.setOnDisabledRule(isRemovedRule);
}
import org.sonar.api.batch.sensor.highlighting.TypeOfText;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.measures.Measure;
import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.index.Cache.Entry;
+++ /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.
- */
-package org.sonar.batch.phases;
-
-import org.sonar.batch.index.ScanPersister;
-import org.sonar.batch.phases.event.PersisterExecutionHandler;
-
-class PersisterExecutionEvent extends AbstractPhaseEvent<PersisterExecutionHandler>
- implements PersisterExecutionHandler.PersisterExecutionEvent {
-
- private final ScanPersister persister;
-
- PersisterExecutionEvent(ScanPersister persister, boolean start) {
- super(start);
- this.persister = persister;
- }
-
- @Override
- public ScanPersister getPersister() {
- return persister;
- }
-
- @Override
- public void dispatch(PersisterExecutionHandler handler) {
- handler.onPersisterExecution(this);
- }
-
- @Override
- public Class getType() {
- return PersisterExecutionHandler.class;
- }
-
-}
+++ /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.
- */
-package org.sonar.batch.phases;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.BatchSide;
-import org.sonar.batch.bootstrap.DefaultAnalysisMode;
-import org.sonar.batch.events.EventBus;
-import org.sonar.batch.index.ScanPersister;
-
-import java.util.Arrays;
-
-@BatchSide
-public class PersistersExecutor {
-
- private static final Logger LOG = LoggerFactory.getLogger(PersistersExecutor.class);
-
- private final ScanPersister[] persisters;
- private final DefaultAnalysisMode analysisMode;
- private final EventBus eventBus;
-
- public PersistersExecutor(DefaultAnalysisMode analysisMode, EventBus eventBus, ScanPersister[] persisters) {
- this.analysisMode = analysisMode;
- this.eventBus = eventBus;
- this.persisters = persisters;
- }
-
- public PersistersExecutor(DefaultAnalysisMode analysisMode, EventBus eventBus) {
- this(analysisMode, eventBus, new ScanPersister[0]);
- }
-
- public void execute() {
- if (analysisMode.isDb()) {
- LOG.info("Store results in database");
- eventBus.fireEvent(new PersistersPhaseEvent(Arrays.asList(persisters), true));
- for (ScanPersister persister : persisters) {
- LOG.debug("Execute {}", persister.getClass().getName());
- eventBus.fireEvent(new PersisterExecutionEvent(persister, true));
- persister.persist();
- eventBus.fireEvent(new PersisterExecutionEvent(persister, false));
- }
-
- eventBus.fireEvent(new PersistersPhaseEvent(Arrays.asList(persisters), false));
- }
- }
-
-}
+++ /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.
- */
-package org.sonar.batch.phases;
-
-import org.sonar.batch.index.ScanPersister;
-import org.sonar.batch.phases.event.PersistersPhaseHandler;
-
-import java.util.List;
-
-class PersistersPhaseEvent extends AbstractPhaseEvent<PersistersPhaseHandler>
- implements PersistersPhaseHandler.PersistersPhaseEvent {
-
- private final List<ScanPersister> persisters;
-
- PersistersPhaseEvent(List<ScanPersister> persisters, boolean start) {
- super(start);
- this.persisters = persisters;
- }
-
- @Override
- public List<ScanPersister> getPersisters() {
- return persisters;
- }
-
- @Override
- protected void dispatch(PersistersPhaseHandler handler) {
- handler.onPersistersPhase(this);
- }
-
- @Override
- protected Class getType() {
- return PersistersPhaseHandler.class;
- }
-
-}
private final SensorContext sensorContext;
private final DefaultIndex index;
private final ProjectInitializer pi;
- private final PersistersExecutor persistersExecutor;
private final FileSystemLogger fsLogger;
private final DefaultModuleFileSystem fs;
private final QProfileVerifier profileVerifier;
InitializersExecutor initializersExecutor, PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor,
SensorContext sensorContext, DefaultIndex index,
EventBus eventBus, ReportPublisher reportPublisher, ProjectInitializer pi,
- PersistersExecutor persistersExecutor, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier,
+ FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier,
IssueExclusionsLoader issueExclusionsLoader, DefaultAnalysisMode analysisMode, LocalIssueTracking localIssueTracking) {
this.decoratorsExecutor = decoratorsExecutor;
this.postJobsExecutor = postJobsExecutor;
this.eventBus = eventBus;
this.reportPublisher = reportPublisher;
this.pi = pi;
- this.persistersExecutor = persistersExecutor;
this.fsLogger = fsLogger;
this.issuesReport = jsonReport;
this.fs = fs;
localIssueTracking();
}
issuesReport();
-
- if (!analysisMode.isPreview()) {
- persistersExecutor.execute();
- }
-
publishReportJob();
postJobsExecutor.execute(sensorContext);
}
cleanMemory();
- eventBus.fireEvent(new ProjectAnalysisEvent(module, false));
+ eventBus.fireEvent(new ProjectAnalysisEvent(module, false));
}
private void publishReportJob() {
+++ /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.
- */
-package org.sonar.batch.phases.event;
-
-import org.sonar.api.batch.events.EventHandler;
-import org.sonar.batch.index.ScanPersister;
-
-public interface PersisterExecutionHandler extends EventHandler {
-
- /**
- * This interface is not intended to be implemented by clients.
- */
- interface PersisterExecutionEvent {
-
- ScanPersister getPersister();
-
- boolean isStart();
-
- boolean isEnd();
-
- }
-
- /**
- * Called before and after execution of {@link ScanPersister}.
- */
- void onPersisterExecution(PersisterExecutionEvent event);
-
-}
+++ /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.
- */
-package org.sonar.batch.phases.event;
-
-import org.sonar.api.batch.events.EventHandler;
-import org.sonar.batch.index.ScanPersister;
-
-import java.util.List;
-
-public interface PersistersPhaseHandler extends EventHandler {
-
- /**
- * This interface is not intended to be implemented by clients.
- */
- interface PersistersPhaseEvent {
-
- /**
- * @return list of Persisters in the order of execution
- */
- List<ScanPersister> getPersisters();
-
- boolean isStart();
-
- boolean isEnd();
-
- }
-
- /**
- * Called before and after execution of all {@link ScanPersister}s.
- */
- void onPersistersPhase(PersistersPhaseEvent event);
-
-}
+++ /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.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.batch.phases.event;
-
-import javax.annotation.ParametersAreNonnullByDefault;
import org.sonar.api.batch.postjob.issue.Issue;
import org.sonar.api.batch.rule.Severity;
import org.sonar.api.config.Settings;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.api.utils.TimeUtils;
import org.sonar.batch.bootstrap.BootstrapProperties;
import org.sonar.batch.events.BatchStepHandler;
-import org.sonar.batch.phases.event.PersisterExecutionHandler;
-import org.sonar.batch.phases.event.PersistersPhaseHandler;
import org.sonar.batch.util.BatchUtils;
import static org.sonar.batch.profiling.AbstractTimeProfiling.sortByDescendingTotalTime;
import static org.sonar.batch.profiling.AbstractTimeProfiling.truncate;
public class PhasesSumUpTimeProfiler implements ProjectAnalysisHandler, SensorExecutionHandler, DecoratorExecutionHandler, PostJobExecutionHandler, DecoratorsPhaseHandler,
- SensorsPhaseHandler, PostJobsPhaseHandler, InitializersPhaseHandler, InitializerExecutionHandler, BatchStepHandler, PersistersPhaseHandler,
- PersisterExecutionHandler {
+ SensorsPhaseHandler, PostJobsPhaseHandler, InitializersPhaseHandler, InitializerExecutionHandler, BatchStepHandler {
static final Logger LOG = LoggerFactory.getLogger(PhasesSumUpTimeProfiler.class);
private static final int TEXT_RIGHT_PAD = 60;
}
}
- @Override
- public void onPersistersPhase(PersistersPhaseEvent event) {
- if (event.isStart()) {
- currentModuleProfiling.addPhaseProfiling(Phase.PERSISTER);
- } else {
- currentModuleProfiling.getProfilingPerPhase(Phase.PERSISTER).stop();
- }
- }
-
- @Override
- public void onPersisterExecution(PersisterExecutionEvent event) {
- PhaseProfiling profiling = currentModuleProfiling.getProfilingPerPhase(Phase.PERSISTER);
- if (event.isStart()) {
- profiling.newItemProfiling(event.getPersister());
- } else {
- profiling.getProfilingPerItem(event.getPersister()).stop();
- }
- }
-
@Override
public void onDecoratorExecution(DecoratorExecutionEvent event) {
PhaseProfiling profiling = currentModuleProfiling.getProfilingPerPhase(Phase.DECORATOR);
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import javax.annotation.Nullable;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
import org.sonar.api.resources.Project;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.batch.scan.ImmutableProjectReactor;
+import org.sonar.core.issue.DefaultIssue;
public class IssuesPublisher implements ReportPublisherStep {
@Override
public void publish(BatchReportWriter writer) {
- Collection<Object> deletedComponentKeys = issueCache.componentKeys();
for (BatchComponent resource : componentCache.all()) {
String componentKey = resource.resource().getEffectiveKey();
Iterable<DefaultIssue> issues = issueCache.byComponent(componentKey);
return toReportIssue(builder, input);
}
}));
- deletedComponentKeys.remove(componentKey);
}
- int count = exportIssuesOfDeletedComponents(deletedComponentKeys, writer);
-
- exportMetadata(writer, count);
+ exportMetadata(writer);
}
- private void exportMetadata(BatchReportWriter writer, int count) {
+ private void exportMetadata(BatchReportWriter writer) {
ProjectDefinition root = reactor.getRoot();
BatchComponent rootProject = componentCache.getRoot();
BatchReport.Metadata.Builder builder = BatchReport.Metadata.newBuilder()
.setAnalysisDate(((Project) rootProject.resource()).getAnalysisDate().getTime())
// Here we want key without branch
.setProjectKey(root.getKey())
- .setRootComponentRef(rootProject.batchId())
- .setDeletedComponentsCount(count);
+ .setRootComponentRef(rootProject.batchId());
String branch = root.properties().get(CoreProperties.PROJECT_BRANCH_PROPERTY);
if (branch != null) {
builder.setBranch(branch);
writer.writeMetadata(builder.build());
}
- private int exportIssuesOfDeletedComponents(Collection<Object> deletedComponentKeys, BatchReportWriter writer) {
- int deletedComponentCount = 0;
- for (Object componentKey : deletedComponentKeys) {
- deletedComponentCount++;
- Iterable<DefaultIssue> issues = issueCache.byComponent(componentKey.toString());
- Iterator<DefaultIssue> iterator = issues.iterator();
- if (iterator.hasNext()) {
- String componentUuid = iterator.next().componentUuid();
- writer.writeDeletedComponentIssues(deletedComponentCount, componentUuid, Iterables.transform(issues, new Function<DefaultIssue, BatchReport.Issue>() {
- private BatchReport.Issue.Builder builder = BatchReport.Issue.newBuilder();
-
- @Override
- public BatchReport.Issue apply(DefaultIssue input) {
- return toReportIssue(builder, input);
- }
- }));
- }
- }
- return deletedComponentCount;
- }
-
private BatchReport.Issue toReportIssue(BatchReport.Issue.Builder builder, DefaultIssue issue) {
builder.clear();
// non-null fields
- builder.setUuid(issue.key());
- builder.setIsNew(issue.isNew());
builder.setSeverity(Constants.Severity.valueOf(issue.severity()));
builder.setRuleRepository(issue.ruleKey().repository());
builder.setRuleKey(issue.ruleKey().rule());
builder.setAttributes(KeyValueFormat.format(issue.attributes()));
builder.addAllTag(issue.tags());
- builder.setMustSendNotification(issue.mustSendNotifications());
- builder.setIsChanged(issue.isChanged());
// nullable fields
Integer line = issue.line();
if (effortToFix != null) {
builder.setEffortToFix(effortToFix);
}
-
Long debtInMinutes = issue.debtInMinutes();
if (debtInMinutes != null) {
builder.setDebtInMinutes(debtInMinutes);
}
- String resolution = issue.resolution();
- if (resolution != null) {
- builder.setResolution(resolution);
- }
- String status = issue.status();
- if (status != null) {
- builder.setStatus(status);
- }
- String checksum = issue.checksum();
- if (checksum != null) {
- builder.setChecksum(checksum);
- }
- builder.setManualSeverity(issue.manualSeverity());
- String reporter = issue.reporter();
- if (reporter != null) {
- builder.setReporter(reporter);
- }
- String assignee = issue.assignee();
- if (assignee != null) {
- builder.setAssignee(assignee);
- }
- String actionPlanKey = issue.actionPlanKey();
- if (actionPlanKey != null) {
- builder.setActionPlanKey(actionPlanKey);
- }
- String authorLogin = issue.authorLogin();
- if (authorLogin != null) {
- builder.setAuthorLogin(authorLogin);
- }
- String diff = diffsToString(issue.currentChange());
- if (diff != null) {
- builder.setDiffFields(diff);
- }
- Date creationDate = issue.creationDate();
- if (creationDate != null) {
- builder.setCreationDate(creationDate.getTime());
- }
- Long selectedAt = issue.selectedAt();
- if (selectedAt != null) {
- builder.setSelectedAt(selectedAt);
- }
- Date closeDate = issue.closeDate();
- if (closeDate != null) {
- builder.setCloseDate(closeDate.getTime());
- }
- Date updateDate = issue.updateDate();
- if (updateDate != null) {
- builder.setUpdateDate(updateDate.getTime());
- }
- return builder.build();
- }
- private String diffsToString(@Nullable FieldDiffs diffs) {
- return diffs != null ? diffs.toString() : null;
+ return builder.build();
}
}
import org.sonar.batch.issue.ignore.scanner.IssueExclusionsRegexpScanner;
import org.sonar.batch.phases.DecoratorsExecutor;
import org.sonar.batch.phases.InitializersExecutor;
-import org.sonar.batch.phases.PersistersExecutor;
import org.sonar.batch.phases.PhaseExecutor;
import org.sonar.batch.phases.PostJobsExecutor;
import org.sonar.batch.phases.ProjectInitializer;
PostJobsExecutor.class,
DecoratorsExecutor.class,
SensorsExecutor.class,
- PersistersExecutor.class,
InitializersExecutor.class,
ProjectInitializer.class,
moduleDefinition.getContainerExtensions(),
import org.sonar.batch.index.DefaultIndex;
import org.sonar.batch.issue.DefaultProjectIssues;
import org.sonar.batch.issue.IssueCache;
-import org.sonar.batch.issue.tracking.InitialOpenIssuesStack;
import org.sonar.batch.issue.tracking.LocalIssueTracking;
import org.sonar.batch.issue.tracking.ServerIssueRepository;
import org.sonar.batch.mediumtest.ScanTaskObservers;
new DebtModelProvider(),
// technical debt
- DefaultTechnicalDebtModel.class,
-
- // Issue tracking
- InitialOpenIssuesStack.class);
+ DefaultTechnicalDebtModel.class);
}
private void addBatchExtensions() {
import org.sonar.api.Property;
import org.sonar.api.PropertyType;
import org.sonar.api.config.Settings;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.Project;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.Rule;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.rule.internal.DefaultActiveRule;
import org.sonar.api.config.Settings;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.platform.Server;
import org.sonar.api.resources.Project;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.config.Settings;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.measures.Formula;
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.PersistenceMode;
import org.sonar.api.component.ResourcePerspectives;
import org.sonar.api.issue.Issuable;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.utils.Duration;
import java.util.Date;
import org.sonar.api.config.Settings;
import org.sonar.api.issue.Issuable;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.Metric;
import java.util.List;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.Project;
import org.sonar.batch.index.BatchComponent;
import com.google.common.collect.Lists;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.Severity;
import javax.annotation.Nullable;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import org.sonar.api.batch.debt.DebtRemediationFunction;
import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
import org.sonar.api.batch.rule.internal.RulesBuilder;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
+++ /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.
- */
-package org.sonar.batch.issue.tracking;
-
-import org.apache.ibatis.session.ResultHandler;
-import org.junit.Test;
-import org.sonar.api.resources.Project;
-import org.sonar.core.issue.db.IssueChangeDao;
-import org.sonar.core.issue.db.IssueDao;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceQuery;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class InitialOpenIssuesSensorTest {
-
- InitialOpenIssuesStack stack = mock(InitialOpenIssuesStack.class);
- IssueDao issueDao = mock(IssueDao.class);
- IssueChangeDao issueChangeDao = mock(IssueChangeDao.class);
- ResourceDao resourceDao = mock(ResourceDao.class);
-
- InitialOpenIssuesSensor sensor = new InitialOpenIssuesSensor(stack, issueDao, issueChangeDao, resourceDao);
-
- @Test
- public void should_select_module_open_issues() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setId(1L));
-
- sensor.analyse(new Project("key"), null);
-
- verify(issueDao).selectNonClosedIssuesByModule(eq(1L), any(ResultHandler.class));
- }
-
- @Test
- public void should_select_module_open_issues_changelog() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setId(1L));
-
- sensor.analyse(new Project("key"), null);
-
- verify(issueChangeDao).selectChangelogOnNonClosedIssuesByModuleAndType(eq(1L), any(ResultHandler.class));
- }
-
- @Test
- public void nothing_to_on_new_component() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(null);
-
- sensor.analyse(new Project("key"), null);
-
- verifyZeroInteractions(issueDao);
- verifyZeroInteractions(issueChangeDao);
- }
-
- @Test
- public void test_toString() throws Exception {
- assertThat(sensor.toString()).isEqualTo("InitialOpenIssuesSensor");
-
- }
-}
+++ /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.
- */
-
-package org.sonar.batch.issue.tracking;
-
-import org.sonar.batch.index.AbstractCachesTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.core.issue.db.IssueChangeDto;
-import org.sonar.core.issue.db.IssueDto;
-
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class InitialOpenIssuesStackTest extends AbstractCachesTest {
-
- InitialOpenIssuesStack stack;
-
- @Before
- public void before() {
- stack = new InitialOpenIssuesStack(caches);
- }
-
- @After
- public void after() {
- caches.stop();
- }
-
- @Test
- public void get_and_remove_issues() {
- IssueDto issueDto = new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1");
- stack.addIssue(issueDto);
-
- List<ServerIssue> issueDtos = stack.selectAndRemoveIssues("org.struts.Action");
- assertThat(issueDtos).hasSize(1);
- assertThat(issueDtos.get(0).key()).isEqualTo("ISSUE-1");
-
- assertThat(stack.selectAllIssues()).isEmpty();
- }
-
- @Test
- public void get_and_remove_with_many_issues_on_same_resource() {
- stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1"));
- stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-2"));
-
- List<ServerIssue> issueDtos = stack.selectAndRemoveIssues("org.struts.Action");
- assertThat(issueDtos).hasSize(2);
-
- assertThat(stack.selectAllIssues()).isEmpty();
- }
-
- @Test
- public void get_and_remove_do_nothing_if_resource_not_found() {
- stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1"));
-
- List<ServerIssue> issueDtos = stack.selectAndRemoveIssues("Other");
- assertThat(issueDtos).hasSize(0);
-
- assertThat(stack.selectAllIssues()).hasSize(1);
- }
-
- @Test
- public void select_changelog() {
- stack.addChangelog(new IssueChangeDto().setKey("CHANGE-1").setIssueKey("ISSUE-1"));
- stack.addChangelog(new IssueChangeDto().setKey("CHANGE-2").setIssueKey("ISSUE-1"));
-
- List<IssueChangeDto> issueChangeDtos = stack.selectChangelog("ISSUE-1");
- assertThat(issueChangeDtos).hasSize(2);
- assertThat(issueChangeDtos.get(0).getKey()).isEqualTo("CHANGE-1");
- assertThat(issueChangeDtos.get(1).getKey()).isEqualTo("CHANGE-2");
- }
-
- @Test
- public void return_empty_changelog() {
- assertThat(stack.selectChangelog("ISSUE-1")).isEmpty();
- }
-
- @Test
- public void clear_issues() {
- stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1"));
-
- assertThat(stack.selectAllIssues()).hasSize(1);
-
- // issues are not removed
- assertThat(stack.selectAllIssues()).hasSize(1);
-
- stack.clear();
- assertThat(stack.selectAllIssues()).isEmpty();
- }
-
- @Test
- public void clear_issues_changelog() {
- stack.addChangelog(new IssueChangeDto().setKey("CHANGE-1").setIssueKey("ISSUE-1"));
-
- assertThat(stack.selectChangelog("ISSUE-1")).hasSize(1);
-
- stack.clear();
- assertThat(stack.selectChangelog("ISSUE-1")).isEmpty();
- }
-}
+++ /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.
- */
-package org.sonar.batch.issue.tracking;
-
-import org.junit.Test;
-import org.mockito.ArgumentMatcher;
-import org.sonar.api.issue.IssueHandler;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.core.issue.IssueUpdater;
-
-import java.util.Date;
-
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-public class IssueHandlersTest {
- @Test
- public void should_execute_handlers() {
- IssueHandler h1 = mock(IssueHandler.class);
- IssueHandler h2 = mock(IssueHandler.class);
- IssueUpdater updater = mock(IssueUpdater.class);
-
- IssueHandlers handlers = new IssueHandlers(updater, new IssueHandler[]{h1, h2});
- final DefaultIssue issue = new DefaultIssue();
- handlers.execute(issue, IssueChangeContext.createScan(new Date()));
-
- verify(h1).onIssue(argThat(new ArgumentMatcher<IssueHandler.Context>() {
- @Override
- public boolean matches(Object o) {
- return ((IssueHandler.Context) o).issue() == issue;
- }
- }));
- }
-
- @Test
- public void test_no_handlers() {
- IssueUpdater updater = mock(IssueUpdater.class);
- IssueHandlers handlers = new IssueHandlers(updater);
- handlers.execute(new DefaultIssue(), IssueChangeContext.createScan(new Date()));
- verifyZeroInteractions(updater);
- }
-}
+++ /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.
- */
-package org.sonar.batch.issue.tracking;
-
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.component.ResourcePerspectives;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
-import org.sonar.api.utils.Duration;
-import org.sonar.api.utils.System2;
-import org.sonar.batch.issue.IssueCache;
-import org.sonar.batch.scan.filesystem.InputPathCache;
-import org.sonar.core.issue.IssueUpdater;
-import org.sonar.core.issue.db.IssueChangeDto;
-import org.sonar.core.issue.db.IssueDto;
-import org.sonar.core.issue.workflow.IssueWorkflow;
-import org.sonar.java.api.JavaClass;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyCollection;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isA;
-import static org.mockito.Mockito.RETURNS_MOCKS;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class IssueTrackingDecoratorTest {
-
- @org.junit.Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- IssueTrackingDecorator decorator;
- IssueCache issueCache = mock(IssueCache.class, RETURNS_MOCKS);
- InitialOpenIssuesStack initialOpenIssues = mock(InitialOpenIssuesStack.class);
- IssueTracking tracking = mock(IssueTracking.class, RETURNS_MOCKS);
- ServerLineHashesLoader lastSnapshots = mock(ServerLineHashesLoader.class);
- IssueHandlers handlers = mock(IssueHandlers.class);
- IssueWorkflow workflow = mock(IssueWorkflow.class);
- IssueUpdater updater = mock(IssueUpdater.class);
- ResourcePerspectives perspectives = mock(ResourcePerspectives.class);
- RulesProfile profile = mock(RulesProfile.class);
- RuleFinder ruleFinder = mock(RuleFinder.class);
- InputPathCache inputPathCache = mock(InputPathCache.class);
-
- @Before
- public void init() {
- decorator = new IssueTrackingDecorator(
- issueCache,
- initialOpenIssues,
- tracking,
- lastSnapshots,
- handlers,
- workflow,
- updater,
- new Project("foo"),
- perspectives,
- profile,
- ruleFinder,
- inputPathCache);
- }
-
- @Test
- public void should_execute_on_project() {
- Project project = mock(Project.class);
- assertThat(decorator.shouldExecuteOnProject(project)).isTrue();
- }
-
- @Test
- public void should_not_be_executed_on_classes_not_methods() {
- DecoratorContext context = mock(DecoratorContext.class);
- decorator.decorate(JavaClass.create("org.foo.Bar"), context);
- verifyZeroInteractions(context, issueCache, tracking, handlers, workflow);
- }
-
- @Test
- public void should_process_open_issues() {
- Resource file = File.create("Action.java").setEffectiveKey("struts:Action.java").setId(123);
- final DefaultIssue issue = new DefaultIssue();
-
- // INPUT : one issue, no open issues during previous scan, no filtering
- when(issueCache.byComponent("struts:Action.java")).thenReturn(Arrays.asList(issue));
- List<ServerIssue> dbIssues = Collections.emptyList();
- when(initialOpenIssues.selectAndRemoveIssues("struts:Action.java")).thenReturn(dbIssues);
- when(inputPathCache.getFile("foo", "Action.java")).thenReturn(mock(DefaultInputFile.class));
- decorator.doDecorate(file);
-
- // Apply filters, track, apply transitions, notify extensions then update cache
- verify(tracking).track(isA(SourceHashHolder.class), eq(dbIssues), argThat(new ArgumentMatcher<Collection<DefaultIssue>>() {
- @Override
- public boolean matches(Object o) {
- List<DefaultIssue> issues = (List<DefaultIssue>) o;
- return issues.size() == 1 && issues.get(0) == issue;
- }
- }));
- verify(workflow).doAutomaticTransition(eq(issue), any(IssueChangeContext.class));
- verify(handlers).execute(eq(issue), any(IssueChangeContext.class));
- verify(issueCache).put(issue);
- }
-
- @Test
- public void should_register_unmatched_issues_as_end_of_life() {
- // "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
- Resource file = File.create("Action.java").setEffectiveKey("struts:Action.java").setId(123);
-
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle"));
-
- IssueTrackingResult trackingResult = new IssueTrackingResult();
- trackingResult.addUnmatched(unmatchedIssue);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
- when(inputPathCache.getFile("foo", "Action.java")).thenReturn(mock(DefaultInputFile.class));
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isTrue();
- }
-
- @Test
- public void manual_issues_should_be_moved_if_matching_line_found() throws Exception {
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(6).setStatus("OPEN").setRuleKey("manual", "Performance"));
- when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
-
- IssueTrackingResult trackingResult = new IssueTrackingResult();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String originalSource = "public interface Action {\n"
- + " void method1();\n"
- + " void method2();\n"
- + " void method3();\n"
- + " void method4();\n"
- + " void method5();\n" // Original issue here
- + "}";
- String newSource = "public interface Action {\n"
- + " void method5();\n" // New issue here
- + " void method1();\n"
- + " void method2();\n"
- + " void method3();\n"
- + " void method4();\n"
- + "}";
- Resource file = mockHashes(originalSource, newSource);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.line()).isEqualTo(2);
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isFalse();
- assertThat(issue.isOnDisabledRule()).isFalse();
- }
-
- private Resource mockHashes(String originalSource, String newSource) throws IOException {
- DefaultInputFile inputFile = mock(DefaultInputFile.class);
- java.io.File f = temp.newFile();
- when(inputFile.path()).thenReturn(f.toPath());
- when(inputFile.file()).thenReturn(f);
- when(inputFile.charset()).thenReturn(StandardCharsets.UTF_8);
- when(inputFile.lines()).thenReturn(StringUtils.countMatches(newSource, "\n") + 1);
- FileUtils.write(f, newSource, StandardCharsets.UTF_8);
- when(inputFile.key()).thenReturn("foo:Action.java");
- when(inputPathCache.getFile("foo", "Action.java")).thenReturn(inputFile);
- when(lastSnapshots.getLineHashes("foo:Action.java")).thenReturn(computeHexHashes(originalSource));
- Resource file = File.create("Action.java");
- return file;
- }
-
- @Test
- public void manual_issues_should_be_untouched_if_already_closed() throws Exception {
-
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("CLOSED").setRuleKey("manual", "Performance"));
- when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
-
- IssueTrackingResult trackingResult = new IssueTrackingResult();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String originalSource = "public interface Action {}";
- Resource file = mockHashes(originalSource, originalSource);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.line()).isEqualTo(1);
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isFalse();
- assertThat(issue.isOnDisabledRule()).isFalse();
- assertThat(issue.status()).isEqualTo("CLOSED");
- }
-
- @Test
- public void manual_issues_should_be_untouched_if_line_is_null() throws Exception {
-
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(null).setStatus("OPEN").setRuleKey("manual", "Performance"));
- when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
-
- IssueTrackingResult trackingResult = new IssueTrackingResult();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String originalSource = "public interface Action {}";
- Resource file = mockHashes(originalSource, originalSource);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.line()).isEqualTo(null);
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isFalse();
- assertThat(issue.isOnDisabledRule()).isFalse();
- assertThat(issue.status()).isEqualTo("OPEN");
- }
-
- @Test
- public void manual_issues_should_be_kept_if_matching_line_not_found() throws Exception {
- // "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
-
- // INPUT : one issue existing during previous scan
- final int issueOnLine = 6;
- ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(issueOnLine).setStatus("OPEN")
- .setRuleKey("manual", "Performance"));
- when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
-
- IssueTrackingResult trackingResult = new IssueTrackingResult();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String originalSource = "public interface Action {\n"
- + " void method1();\n"
- + " void method2();\n"
- + " void method3();\n"
- + " void method4();\n"
- + " void method5();\n" // Original issue here
- + "}";
- String newSource = "public interface Action {\n"
- + " void method1();\n"
- + " void method2();\n"
- + " void method3();\n"
- + " void method4();\n"
- + " void method6();\n" // Poof, no method5 anymore
- + "}";
-
- Resource file = mockHashes(originalSource, newSource);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.line()).isEqualTo(issueOnLine);
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isFalse();
- assertThat(issue.isOnDisabledRule()).isFalse();
- }
-
- @Test
- public void manual_issues_should_be_kept_if_multiple_matching_lines_found() throws Exception {
- // "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
-
- // INPUT : one issue existing during previous scan
- final int issueOnLine = 3;
- ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(issueOnLine).setStatus("OPEN")
- .setRuleKey("manual", "Performance"));
- when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
-
- IssueTrackingResult trackingResult = new IssueTrackingResult();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String originalSource = "public class Action {\n"
- + " void method1() {\n"
- + " notify();\n" // initial issue
- + " }\n"
- + "}";
- String newSource = "public class Action {\n"
- + " \n"
- + " void method1() {\n" // new issue will appear here
- + " notify();\n"
- + " }\n"
- + " void method2() {\n"
- + " notify();\n"
- + " }\n"
- + "}";
- Resource file = mockHashes(originalSource, newSource);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.line()).isEqualTo(issueOnLine);
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isFalse();
- assertThat(issue.isOnDisabledRule()).isFalse();
- }
-
- @Test
- public void manual_issues_should_be_closed_if_manual_rule_is_removed() throws Exception {
- // "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
-
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("OPEN").setRuleKey("manual", "Performance"));
- when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance").setStatus(Rule.STATUS_REMOVED));
-
- IssueTrackingResult trackingResult = new IssueTrackingResult();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String source = "public interface Action {}";
- Resource file = mockHashes(source, source);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isTrue();
- assertThat(issue.isOnDisabledRule()).isTrue();
- }
-
- @Test
- public void manual_issues_should_be_closed_if_manual_rule_is_not_found() throws Exception {
- // "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
-
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("OPEN").setRuleKey("manual", "Performance"));
- when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(null);
-
- IssueTrackingResult trackingResult = new IssueTrackingResult();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String source = "public interface Action {}";
- Resource file = mockHashes(source, source);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isTrue();
- assertThat(issue.isOnDisabledRule()).isTrue();
- }
-
- @Test
- public void manual_issues_should_be_closed_if_new_source_is_shorter() throws Exception {
- // "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
-
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(6).setStatus("OPEN").setRuleKey("manual", "Performance"));
- when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(null);
-
- IssueTrackingResult trackingResult = new IssueTrackingResult();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String originalSource = "public interface Action {\n"
- + " void method1();\n"
- + " void method2();\n"
- + " void method3();\n"
- + " void method4();\n"
- + " void method5();\n"
- + "}";
- String newSource = "public interface Action {\n"
- + " void method1();\n"
- + " void method2();\n"
- + "}";
- Resource file = mockHashes(originalSource, newSource);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- verify(updater).setResolution(eq(issue), eq(Issue.RESOLUTION_REMOVED), any(IssueChangeContext.class));
- verify(updater).setStatus(eq(issue), eq(Issue.STATUS_CLOSED), any(IssueChangeContext.class));
-
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isTrue();
- assertThat(issue.isOnDisabledRule()).isTrue();
- }
-
- @Test
- public void should_register_issues_on_deleted_components() {
- Project project = new Project("struts");
- DefaultIssue openIssue = new DefaultIssue();
- when(issueCache.byComponent("struts")).thenReturn(Arrays.asList(openIssue));
- IssueDto deadIssue = new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle");
- when(initialOpenIssues.selectAllIssues()).thenReturn(Arrays.asList(deadIssue));
-
- decorator.doDecorate(project);
-
- // the dead issue must be closed -> apply automatic transition, notify handlers and add to cache
- verify(workflow, times(2)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(2)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(issueCache, times(2)).put(any(DefaultIssue.class));
-
- verify(issueCache).put(argThat(new ArgumentMatcher<DefaultIssue>() {
- @Override
- public boolean matches(Object o) {
- DefaultIssue dead = (DefaultIssue) o;
- return "ABCDE".equals(dead.key()) && !dead.isNew() && dead.isEndOfLife();
- }
- }));
- }
-
- @Test
- public void merge_matched_issue() {
- ServerIssue previousIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
- .setLine(10).setSeverity("MAJOR").setMessage("Message").setEffortToFix(1.5).setDebt(1L).setProjectKey("sample"));
- DefaultIssue issue = new DefaultIssue();
-
- IssueTrackingResult trackingResult = mock(IssueTrackingResult.class);
- when(trackingResult.matched()).thenReturn(newArrayList(issue));
- when(trackingResult.matching(eq(issue))).thenReturn(previousIssue);
- decorator.mergeMatched(trackingResult);
-
- verify(updater).setPastSeverity(eq(issue), eq("MAJOR"), any(IssueChangeContext.class));
- verify(updater).setPastLine(eq(issue), eq(10));
- verify(updater).setPastMessage(eq(issue), eq("Message"), any(IssueChangeContext.class));
- verify(updater).setPastEffortToFix(eq(issue), eq(1.5), any(IssueChangeContext.class));
- verify(updater).setPastTechnicalDebt(eq(issue), eq(Duration.create(1L)), any(IssueChangeContext.class));
- verify(updater).setPastProject(eq(issue), eq("sample"), any(IssueChangeContext.class));
- }
-
- @Test
- public void merge_matched_issue_on_manual_severity() {
- ServerIssue previousIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
- .setLine(10).setManualSeverity(true).setSeverity("MAJOR").setMessage("Message").setEffortToFix(1.5).setDebt(1L));
- DefaultIssue issue = new DefaultIssue();
-
- IssueTrackingResult trackingResult = mock(IssueTrackingResult.class);
- when(trackingResult.matched()).thenReturn(newArrayList(issue));
- when(trackingResult.matching(eq(issue))).thenReturn(previousIssue);
- decorator.mergeMatched(trackingResult);
-
- assertThat(issue.manualSeverity()).isTrue();
- assertThat(issue.severity()).isEqualTo("MAJOR");
- verify(updater, never()).setPastSeverity(eq(issue), anyString(), any(IssueChangeContext.class));
- }
-
- @Test
- public void merge_issue_changelog_with_previous_changelog() {
- when(initialOpenIssues.selectChangelog("ABCDE")).thenReturn(newArrayList(new IssueChangeDto().setIssueKey("ABCD").setCreatedAt(System2.INSTANCE.now())));
-
- ServerIssue previousIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
- .setLine(10).setMessage("Message").setEffortToFix(1.5).setDebt(1L).setCreatedAt(System2.INSTANCE.now()));
- DefaultIssue issue = new DefaultIssue();
-
- IssueTrackingResult trackingResult = mock(IssueTrackingResult.class);
- when(trackingResult.matched()).thenReturn(newArrayList(issue));
- when(trackingResult.matching(eq(issue))).thenReturn(previousIssue);
- decorator.mergeMatched(trackingResult);
-
- assertThat(issue.changes()).hasSize(1);
- }
-
- private String[] computeHexHashes(String source) {
- String[] lines = source.split("\n");
- String[] hashes = new String[lines.length];
- for (int i = 0; i < lines.length; i++) {
- hashes[i] = DigestUtils.md5Hex(lines[i].replaceAll("[\t ]", ""));
- }
- return hashes;
- }
-
-}
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.batch.postjob.issue.Issue;
import org.sonar.api.batch.rule.Severity;
import org.sonar.api.config.Settings;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.File;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.issue.IssueCache;
package org.sonar.batch.profiling;
import com.google.common.collect.Maps;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.System2;
import org.sonar.batch.bootstrap.BootstrapProperties;
import org.sonar.batch.events.BatchStepEvent;
-import org.sonar.batch.index.ScanPersister;
-import org.sonar.batch.phases.event.PersisterExecutionHandler;
-import org.sonar.batch.phases.event.PersistersPhaseHandler;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.spy;
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.INIT).getProfilingPerItem(new FakeInitializer()).totalTime()).isEqualTo(7L);
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.SENSOR).getProfilingPerItem(new FakeSensor()).totalTime()).isEqualTo(10L);
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator1()).totalTime()).isEqualTo(20L);
- assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.PERSISTER).getProfilingPerItem(new FakeScanPersister()).totalTime()).isEqualTo(40L);
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.POSTJOB).getProfilingPerItem(new FakePostJob()).totalTime()).isEqualTo(30L);
assertThat(profiler.currentModuleProfiling.getProfilingPerBatchStep("Free memory").totalTime()).isEqualTo(9L);
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.SENSOR).getProfilingPerItem(new FakeSensor()).totalTime()).isEqualTo(10L);
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator1()).totalTime()).isEqualTo(20L);
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator2()).totalTime()).isEqualTo(10L);
- assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.PERSISTER).getProfilingPerItem(new FakeScanPersister()).totalTime()).isEqualTo(40L);
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.POSTJOB).getProfilingPerItem(new FakePostJob()).totalTime()).isEqualTo(30L);
assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.INIT).getProfilingPerItem(new FakeInitializer()).totalTime()).isEqualTo(21L);
assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.SENSOR).getProfilingPerItem(new FakeSensor()).totalTime()).isEqualTo(30L);
assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator1()).totalTime()).isEqualTo(60L);
assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator2()).totalTime()).isEqualTo(30L);
- assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.PERSISTER).getProfilingPerItem(new FakeScanPersister()).totalTime()).isEqualTo(120L);
assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.POSTJOB).getProfilingPerItem(new FakePostJob()).totalTime()).isEqualTo(90L);
}
initializerPhase(profiler);
sensorPhase(profiler);
decoratorPhase(profiler);
- persistersPhase(profiler);
postJobPhase(profiler);
batchStep(profiler);
// End of moduleA
profiler.onSensorsPhase(sensorsEvent(false));
}
- private void persistersPhase(PhasesSumUpTimeProfiler profiler) {
- ScanPersister persister = new FakeScanPersister();
- // Start of persister phase
- profiler.onPersistersPhase(persistersEvent(true));
- // Start of a ScanPersister
- profiler.onPersisterExecution(persisterEvent(persister, true));
- clock.sleep(40);
- // End of a ScanPersister
- profiler.onPersisterExecution(persisterEvent(persister, false));
- // End of persister phase
- profiler.onPersistersPhase(persistersEvent(false));
- }
-
private void postJobPhase(PhasesSumUpTimeProfiler profiler) {
PostJob postJob = new FakePostJob();
// Start of sensor phase
};
}
- private PersisterExecutionHandler.PersisterExecutionEvent persisterEvent(final ScanPersister persister, final boolean start) {
- return new PersisterExecutionHandler.PersisterExecutionEvent() {
-
- @Override
- public boolean isStart() {
- return start;
- }
-
- @Override
- public boolean isEnd() {
- return !start;
- }
-
- @Override
- public ScanPersister getPersister() {
- return persister;
- }
- };
- }
-
private SensorsPhaseEvent sensorsEvent(final boolean start) {
return new SensorsPhaseHandler.SensorsPhaseEvent() {
};
}
- private PersistersPhaseHandler.PersistersPhaseEvent persistersEvent(final boolean start) {
- return new PersistersPhaseHandler.PersistersPhaseEvent() {
-
- @Override
- public boolean isStart() {
- return start;
- }
-
- @Override
- public boolean isEnd() {
- return !start;
- }
-
- @Override
- public List<ScanPersister> getPersisters() {
- return null;
- }
- };
- }
-
private DecoratorsPhaseHandler.DecoratorsPhaseEvent decoratorsEvent(final boolean start) {
return new DecoratorsPhaseHandler.DecoratorsPhaseEvent() {
public void executeOn(Project project, SensorContext context) {
}
}
-
- public class FakeScanPersister implements ScanPersister {
- @Override
- public void persist() {
- }
- }
}
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
import org.sonar.api.resources.Project;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.Duration;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.batch.scan.ImmutableProjectReactor;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyString;
Metadata metadata = reader.readMetadata();
assertThat(metadata.getAnalysisDate()).isEqualTo(1234567L);
assertThat(metadata.getProjectKey()).isEqualTo("foo");
- assertThat(metadata.getDeletedComponentsCount()).isEqualTo(0);
assertThat(reader.readComponentIssues(1)).hasSize(0);
assertThat(reader.readComponentIssues(2)).hasSize(2);
}
@Test
- public void publishMatadataWithBranch() throws Exception {
+ public void publishMetadataWithBranch() throws Exception {
root.properties().put(CoreProperties.PROJECT_BRANCH_PROPERTY, "myBranch");
p.setKey("foo:myBranch");
p.setEffectiveKey("foo:myBranch");
assertThat(metadata.getAnalysisDate()).isEqualTo(1234567L);
assertThat(metadata.getProjectKey()).isEqualTo("foo");
assertThat(metadata.getBranch()).isEqualTo("myBranch");
- assertThat(metadata.getDeletedComponentsCount()).isEqualTo(0);
}
- @Test
- public void publishIssuesOfDeletedComponents() throws Exception {
-
- DefaultIssue issue1 = new DefaultIssue();
- issue1.setKey("uuid");
- issue1.setComponentUuid("deletedUuid");
- issue1.setSeverity("MAJOR");
- issue1.setRuleKey(RuleKey.of("repo", "rule"));
- DefaultIssue issue2 = new DefaultIssue();
- issue2.setKey("uuid2");
- issue2.setComponentUuid("deletedUuid");
- issue2.setSeverity("MAJOR");
- issue2.setRuleKey(RuleKey.of("repo", "rule"));
- issue2.setLine(2);
- issue2.setMessage("msg");
- issue2.setEffortToFix(2d);
- issue2.setDebt(Duration.create(2));
- issue2.setResolution("FIXED");
- issue2.setStatus("RESOLVED");
- issue2.setChecksum("checksum");
- issue2.setReporter("reporter");
- issue2.setAssignee("assignee");
- issue2.setActionPlanKey("action");
- issue2.setAuthorLogin("author");
- issue2.setCurrentChange(new FieldDiffs().setUserLogin("foo"));
- issue2.setCreationDate(new Date());
- issue2.setUpdateDate(new Date());
- issue2.setCloseDate(new Date());
- issue2.setSelectedAt(1234L);
-
- when(issueCache.byComponent("foo:deleted.php")).thenReturn(Arrays.asList(issue1, issue2));
-
- when(issueCache.componentKeys()).thenReturn(Arrays.<Object>asList("foo:deleted.php"));
-
- File outputDir = temp.newFolder();
- BatchReportWriter writer = new BatchReportWriter(outputDir);
-
- publisher.publish(writer);
-
- BatchReportReader reader = new BatchReportReader(outputDir);
- Metadata metadata = reader.readMetadata();
- assertThat(metadata.getDeletedComponentsCount()).isEqualTo(1);
-
- assertThat(reader.readComponentIssues(1)).hasSize(0);
- assertThat(reader.readComponentIssues(2)).hasSize(0);
- assertThat(reader.readDeletedComponentIssues(1).getComponentUuid()).isEqualTo("deletedUuid");
- assertThat(reader.readDeletedComponentIssues(1).getIssueList()).hasSize(2);
-
- }
}
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.config.Settings;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.log.LogTester;
import org.sonar.batch.issue.IssueCache;
import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
import org.sonar.api.config.Settings;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.platform.Server;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
public void shouldAddIssueOnFile() {
InputFile file = new DefaultInputFile("foo", "src/Foo.php").setLines(4);
- ArgumentCaptor<org.sonar.api.issue.internal.DefaultIssue> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.issue.internal.DefaultIssue.class);
+ ArgumentCaptor<org.sonar.core.issue.DefaultIssue> argumentCaptor = ArgumentCaptor.forClass(org.sonar.core.issue.DefaultIssue.class);
sensorStorage.store(new DefaultIssue()
.onFile(file)
verify(moduleIssues).initAndAddIssue(argumentCaptor.capture());
- org.sonar.api.issue.internal.DefaultIssue issue = argumentCaptor.getValue();
+ org.sonar.core.issue.DefaultIssue issue = argumentCaptor.getValue();
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("foo", "bar"));
assertThat(issue.message()).isEqualTo("Foo");
assertThat(issue.line()).isEqualTo(3);
public void shouldAddIssueOnDirectory() {
InputDir dir = new DefaultInputDir("foo", "src");
- ArgumentCaptor<org.sonar.api.issue.internal.DefaultIssue> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.issue.internal.DefaultIssue.class);
+ ArgumentCaptor<org.sonar.core.issue.DefaultIssue> argumentCaptor = ArgumentCaptor.forClass(org.sonar.core.issue.DefaultIssue.class);
sensorStorage.store(new DefaultIssue()
.onDir(dir)
verify(moduleIssues).initAndAddIssue(argumentCaptor.capture());
- org.sonar.api.issue.internal.DefaultIssue issue = argumentCaptor.getValue();
+ org.sonar.core.issue.DefaultIssue issue = argumentCaptor.getValue();
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("foo", "bar"));
assertThat(issue.message()).isEqualTo("Foo");
assertThat(issue.line()).isNull();
@Test
public void shouldAddIssueOnProject() {
- ArgumentCaptor<org.sonar.api.issue.internal.DefaultIssue> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.issue.internal.DefaultIssue.class);
+ ArgumentCaptor<org.sonar.core.issue.DefaultIssue> argumentCaptor = ArgumentCaptor.forClass(org.sonar.core.issue.DefaultIssue.class);
sensorStorage.store(new DefaultIssue()
.onProject()
verify(moduleIssues).initAndAddIssue(argumentCaptor.capture());
- org.sonar.api.issue.internal.DefaultIssue issue = argumentCaptor.getValue();
+ org.sonar.core.issue.DefaultIssue issue = argumentCaptor.getValue();
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("foo", "bar"));
assertThat(issue.message()).isEqualTo("Foo");
assertThat(issue.line()).isNull();
--- /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.
+ */
+package org.sonar.core.issue;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.commons.lang.time.DateUtils;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.IssueComment;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.utils.Duration;
+import org.sonar.core.issue.tracking.Trackable;
+
+/**
+ * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING.
+ *
+ * @since 3.6
+ */
+public class DefaultIssue implements Issue, Trackable {
+
+ private String key;
+
+ private String componentUuid;
+ private String componentKey;
+
+ private String moduleUuid;
+ private String moduleUuidPath;
+
+ private String projectUuid;
+ private String projectKey;
+
+ private RuleKey ruleKey;
+ private String language;
+ private String severity;
+ private boolean manualSeverity = false;
+ private String message;
+ private Integer line;
+ private Double effortToFix;
+ private Duration debt;
+ private String status;
+ private String resolution;
+ private String reporter;
+ private String assignee;
+ private String checksum;
+ private Map<String, String> attributes = null;
+ private String authorLogin = null;
+ private String actionPlanKey;
+ private List<IssueComment> comments = null;
+ private Set<String> tags = null;
+
+ // FUNCTIONAL DATES
+ private Date creationDate;
+ private Date updateDate;
+ private Date closeDate;
+
+ // FOLLOWING FIELDS ARE AVAILABLE ONLY DURING SCAN
+
+ // Current changes
+ private FieldDiffs currentChange = null;
+
+ // all changes
+ private List<FieldDiffs> changes = null;
+
+ // true if the the issue did not exist in the previous scan.
+ private boolean isNew = true;
+
+ // True if the the issue did exist in the previous scan but not in the current one. That means
+ // that this issue should be closed.
+ private boolean beingClosed = false;
+
+ private boolean onDisabledRule = false;
+
+ // true if some fields have been changed since the previous scan
+ private boolean isChanged = false;
+
+ // true if notifications have to be sent
+ private boolean sendNotifications = false;
+
+ // Date when issue was loaded from db (only when isNew=false)
+ private Long selectedAt;
+
+ @Override
+ public String key() {
+ return key;
+ }
+
+ public DefaultIssue setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+ /**
+ * Can be null on Views or Devs
+ */
+ @Override
+ @CheckForNull
+ public String componentUuid() {
+ return componentUuid;
+ }
+
+ public DefaultIssue setComponentUuid(@CheckForNull String componentUuid) {
+ this.componentUuid = componentUuid;
+ return this;
+ }
+
+ @Override
+ public String componentKey() {
+ return componentKey;
+ }
+
+ public DefaultIssue setComponentKey(String s) {
+ this.componentKey = s;
+ return this;
+ }
+
+ @CheckForNull
+ public String moduleUuid() {
+ return moduleUuid;
+ }
+
+ public DefaultIssue setModuleUuid(@Nullable String moduleUuid) {
+ this.moduleUuid = moduleUuid;
+ return this;
+ }
+
+ @CheckForNull
+ public String moduleUuidPath() {
+ return moduleUuidPath;
+ }
+
+ public DefaultIssue setModuleUuidPath(@Nullable String moduleUuidPath) {
+ this.moduleUuidPath = moduleUuidPath;
+ return this;
+ }
+
+ /**
+ * Can be null on Views or Devs
+ */
+ @Override
+ @CheckForNull
+ public String projectUuid() {
+ return projectUuid;
+ }
+
+ public DefaultIssue setProjectUuid(@Nullable String projectUuid) {
+ this.projectUuid = projectUuid;
+ return this;
+ }
+
+ @Override
+ public String projectKey() {
+ return projectKey;
+ }
+
+ public DefaultIssue setProjectKey(String projectKey) {
+ this.projectKey = projectKey;
+ return this;
+ }
+
+ @Override
+ public RuleKey ruleKey() {
+ return ruleKey;
+ }
+
+ public DefaultIssue setRuleKey(RuleKey k) {
+ this.ruleKey = k;
+ return this;
+ }
+
+ @Override
+ public String language() {
+ return language;
+ }
+
+ public DefaultIssue setLanguage(String l) {
+ this.language = l;
+ return this;
+ }
+
+ @Override
+ public String severity() {
+ return severity;
+ }
+
+ public DefaultIssue setSeverity(@Nullable String s) {
+ Preconditions.checkArgument(s == null || Severity.ALL.contains(s), "Not a valid severity: " + s);
+ this.severity = s;
+ return this;
+ }
+
+ public boolean manualSeverity() {
+ return manualSeverity;
+ }
+
+ public DefaultIssue setManualSeverity(boolean b) {
+ this.manualSeverity = b;
+ return this;
+ }
+
+ @Override
+ @CheckForNull
+ public String message() {
+ return message;
+ }
+
+ public DefaultIssue setMessage(@Nullable String s) {
+ this.message = StringUtils.abbreviate(StringUtils.trim(s), MESSAGE_MAX_SIZE);
+ return this;
+ }
+
+ @Override
+ @CheckForNull
+ public Integer line() {
+ return line;
+ }
+
+ public DefaultIssue setLine(@Nullable Integer l) {
+ Preconditions.checkArgument(l == null || l > 0, "Line must be null or greater than zero (got " + l + ")");
+ this.line = l;
+ return this;
+ }
+
+ @Override
+ @CheckForNull
+ public Double effortToFix() {
+ return effortToFix;
+ }
+
+ public DefaultIssue setEffortToFix(@Nullable Double d) {
+ Preconditions.checkArgument(d == null || d >= 0, "Effort to fix must be greater than or equal 0 (got " + d + ")");
+ this.effortToFix = d;
+ return this;
+ }
+
+ /**
+ * Elapsed time to fix the issue
+ */
+ @Override
+ @CheckForNull
+ public Duration debt() {
+ return debt;
+ }
+
+ @CheckForNull
+ public Long debtInMinutes() {
+ return debt != null ? debt.toMinutes() : null;
+ }
+
+ public DefaultIssue setDebt(@Nullable Duration t) {
+ this.debt = t;
+ return this;
+ }
+
+ @Override
+ public String status() {
+ return status;
+ }
+
+ public DefaultIssue setStatus(String s) {
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(s), "Status must be set");
+ this.status = s;
+ return this;
+ }
+
+ @Override
+ @CheckForNull
+ public String resolution() {
+ return resolution;
+ }
+
+ public DefaultIssue setResolution(@Nullable String s) {
+ this.resolution = s;
+ return this;
+ }
+
+ @Override
+ @CheckForNull
+ public String reporter() {
+ return reporter;
+ }
+
+ public DefaultIssue setReporter(@Nullable String s) {
+ this.reporter = s;
+ return this;
+ }
+
+ @Override
+ @CheckForNull
+ public String assignee() {
+ return assignee;
+ }
+
+ public DefaultIssue setAssignee(@Nullable String s) {
+ this.assignee = s;
+ return this;
+ }
+
+ @Override
+ public Date creationDate() {
+ return creationDate;
+ }
+
+ public DefaultIssue setCreationDate(Date d) {
+ // d is not marked as Nullable but we still allow null parameter for unit testing.
+ this.creationDate = (d != null ? DateUtils.truncate(d, Calendar.SECOND) : null);
+ return this;
+ }
+
+ @Override
+ @CheckForNull
+ public Date updateDate() {
+ return updateDate;
+ }
+
+ public DefaultIssue setUpdateDate(@Nullable Date d) {
+ this.updateDate = (d != null ? DateUtils.truncate(d, Calendar.SECOND) : null);
+ return this;
+ }
+
+ @Override
+ @CheckForNull
+ public Date closeDate() {
+ return closeDate;
+ }
+
+ public DefaultIssue setCloseDate(@Nullable Date d) {
+ this.closeDate = (d != null ? DateUtils.truncate(d, Calendar.SECOND) : null);
+ return this;
+ }
+
+ @CheckForNull
+ public String checksum() {
+ return checksum;
+ }
+
+ public DefaultIssue setChecksum(@Nullable String s) {
+ this.checksum = s;
+ return this;
+ }
+
+ @Override
+ public boolean isNew() {
+ return isNew;
+ }
+
+ public DefaultIssue setNew(boolean b) {
+ isNew = b;
+ return this;
+ }
+
+ /**
+ * True when one of the following conditions is true :
+ * <ul>
+ * <li>the related component has been deleted or renamed</li>
+ * <li>the rule has been deleted (eg. on plugin uninstall)</li>
+ * <li>the rule has been disabled in the Quality profile</li>
+ * </ul>
+ */
+ public boolean isBeingClosed() {
+ return beingClosed;
+ }
+
+ public DefaultIssue setBeingClosed(boolean b) {
+ beingClosed = b;
+ return this;
+ }
+
+ public boolean isOnDisabledRule() {
+ return onDisabledRule;
+ }
+
+ public DefaultIssue setOnDisabledRule(boolean b) {
+ onDisabledRule = b;
+ return this;
+ }
+
+ public boolean isChanged() {
+ return isChanged;
+ }
+
+ public DefaultIssue setChanged(boolean b) {
+ isChanged = b;
+ return this;
+ }
+
+ public boolean mustSendNotifications() {
+ return sendNotifications;
+ }
+
+ public DefaultIssue setSendNotifications(boolean b) {
+ sendNotifications = b;
+ return this;
+ }
+
+ @Override
+ @CheckForNull
+ public String attribute(String key) {
+ return attributes == null ? null : attributes.get(key);
+ }
+
+ public DefaultIssue setAttribute(String key, @Nullable String value) {
+ if (attributes == null) {
+ attributes = Maps.newHashMap();
+ }
+ if (value == null) {
+ attributes.remove(key);
+ } else {
+ attributes.put(key, value);
+ }
+ return this;
+ }
+
+ @Override
+ public Map<String, String> attributes() {
+ return attributes == null ? Collections.<String, String>emptyMap() : ImmutableMap.copyOf(attributes);
+ }
+
+ public DefaultIssue setAttributes(@Nullable Map<String, String> map) {
+ if (map != null) {
+ if (attributes == null) {
+ attributes = Maps.newHashMap();
+ }
+ attributes.putAll(map);
+ }
+ return this;
+ }
+
+ @Override
+ @CheckForNull
+ public String authorLogin() {
+ return authorLogin;
+ }
+
+ public DefaultIssue setAuthorLogin(@Nullable String s) {
+ this.authorLogin = s;
+ return this;
+ }
+
+ @Override
+ @CheckForNull
+ public String actionPlanKey() {
+ return actionPlanKey;
+ }
+
+ public DefaultIssue setActionPlanKey(@Nullable String actionPlanKey) {
+ this.actionPlanKey = actionPlanKey;
+ return this;
+ }
+
+ public DefaultIssue setFieldChange(IssueChangeContext context, String field, @Nullable Serializable oldValue, @Nullable Serializable newValue) {
+ if (!Objects.equal(oldValue, newValue)) {
+ if (currentChange == null) {
+ currentChange = new FieldDiffs();
+ currentChange.setUserLogin(context.login());
+ currentChange.setCreationDate(context.date());
+ }
+ currentChange.setDiff(field, oldValue, newValue);
+ }
+ addChange(currentChange);
+ return this;
+ }
+
+ public DefaultIssue setCurrentChange(FieldDiffs currentChange) {
+ this.currentChange = currentChange;
+ addChange(currentChange);
+ return this;
+ }
+
+ @CheckForNull
+ public FieldDiffs currentChange() {
+ return currentChange;
+ }
+
+ public DefaultIssue addChange(FieldDiffs change) {
+ if (changes == null) {
+ changes = new ArrayList<>();
+ }
+ changes.add(change);
+ return this;
+ }
+
+ public DefaultIssue setChanges(List<FieldDiffs> changes) {
+ this.changes = changes;
+ return this;
+ }
+
+ public List<FieldDiffs> changes() {
+ if (changes == null) {
+ return Collections.emptyList();
+ }
+ return ImmutableList.copyOf(changes);
+ }
+
+ public DefaultIssue addComment(DefaultIssueComment comment) {
+ if (comments == null) {
+ comments = new ArrayList<>();
+ }
+ comments.add(comment);
+ return this;
+ }
+
+ @Override
+ public List<IssueComment> comments() {
+ if (comments == null) {
+ return Collections.emptyList();
+ }
+ return ImmutableList.copyOf(comments);
+ }
+
+ @CheckForNull
+ public Long selectedAt() {
+ return selectedAt;
+ }
+
+ public DefaultIssue setSelectedAt(@Nullable Long d) {
+ this.selectedAt = d;
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ DefaultIssue that = (DefaultIssue) o;
+ return !(key != null ? !key.equals(that.key) : (that.key != null));
+ }
+
+ @Override
+ public int hashCode() {
+ return key != null ? key.hashCode() : 0;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
+ }
+
+ @Override
+ public Set<String> tags() {
+ if (tags == null) {
+ return ImmutableSet.of();
+ } else {
+ return ImmutableSet.copyOf(tags);
+ }
+ }
+
+ public DefaultIssue setTags(Collection<String> tags) {
+ this.tags = new LinkedHashSet<>(tags);
+ return this;
+ }
+
+ @Override
+ public Integer getLine() {
+ return line;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+
+ @Override
+ public String getLineHash() {
+ return checksum;
+ }
+
+ @Override
+ public RuleKey getRuleKey() {
+ return ruleKey;
+ }
+}
import com.google.common.collect.Maps;
import org.sonar.api.issue.Issuable;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.internal.Uuids;
issue.setStatus(Issue.STATUS_OPEN);
issue.setCloseDate(null);
issue.setNew(true);
- issue.setEndOfLife(false);
+ issue.setBeingClosed(false);
issue.setOnDisabledRule(false);
return issue;
}
--- /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.
+ */
+package org.sonar.core.issue;
+
+import org.sonar.api.issue.IssueComment;
+import org.sonar.api.utils.internal.Uuids;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING.
+ *
+ * @since 3.6
+ */
+public class DefaultIssueComment implements Serializable, IssueComment {
+
+ private String issueKey;
+ private String userLogin;
+ private Date createdAt;
+ private Date updatedAt;
+ private String key;
+ private String markdownText;
+ private boolean isNew;
+
+ public static DefaultIssueComment create(String issueKey, @Nullable String login, String markdownText) {
+ DefaultIssueComment comment = new DefaultIssueComment();
+ comment.setIssueKey(issueKey);
+ comment.setKey(Uuids.create());
+ Date now = new Date();
+ comment.setUserLogin(login);
+ comment.setMarkdownText(markdownText);
+ comment.setCreatedAt(now).setUpdatedAt(now);
+ comment.setNew(true);
+ return comment;
+ }
+
+ @Override
+ public String markdownText() {
+ return markdownText;
+ }
+
+ public DefaultIssueComment setMarkdownText(String s) {
+ this.markdownText = s;
+ return this;
+ }
+
+ @Override
+ public String issueKey() {
+ return issueKey;
+ }
+
+ public DefaultIssueComment setIssueKey(String s) {
+ this.issueKey = s;
+ return this;
+ }
+
+ @Override
+ public String key() {
+ return key;
+ }
+
+ public DefaultIssueComment setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+ /**
+ * The user who created the comment. Null if it was automatically generated during project scan.
+ */
+ @Override
+ @CheckForNull
+ public String userLogin() {
+ return userLogin;
+ }
+
+ public DefaultIssueComment setUserLogin(@Nullable String userLogin) {
+ this.userLogin = userLogin;
+ return this;
+ }
+
+ @Override
+ public Date createdAt() {
+ return createdAt;
+ }
+
+ public DefaultIssueComment setCreatedAt(Date createdAt) {
+ this.createdAt = createdAt;
+ return this;
+ }
+
+ @Override
+ public Date updatedAt() {
+ return updatedAt;
+ }
+
+ public DefaultIssueComment setUpdatedAt(@Nullable Date updatedAt) {
+ this.updatedAt = updatedAt;
+ return this;
+ }
+
+ public boolean isNew() {
+ return isNew;
+ }
+
+ public DefaultIssueComment setNew(boolean b) {
+ isNew = b;
+ return this;
+ }
+}
--- /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.
+ */
+package org.sonar.core.issue;
+
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.common.collect.Maps;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Map;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+/**
+ * PLUGINS MUST NOT USE THIS CLASS, EXCEPT FOR UNIT TESTING.
+ *
+ * @since 3.6
+ */
+public class FieldDiffs implements Serializable {
+
+ public static final Splitter FIELDS_SPLITTER = Splitter.on(',').omitEmptyStrings();
+
+ private String issueKey;
+ private String userLogin;
+ private Date creationDate;
+
+ private final Map<String, Diff> diffs = Maps.newLinkedHashMap();
+
+ public Map<String, Diff> diffs() {
+ return diffs;
+ }
+
+ public Diff get(String field) {
+ return diffs.get(field);
+ }
+
+ @CheckForNull
+ public String userLogin() {
+ return userLogin;
+ }
+
+ public FieldDiffs setUserLogin(@Nullable String s) {
+ this.userLogin = s;
+ return this;
+ }
+
+ public Date creationDate() {
+ return creationDate;
+ }
+
+ public FieldDiffs setCreationDate(Date creationDate) {
+ this.creationDate = creationDate;
+ return this;
+ }
+
+ public String issueKey() {
+ return issueKey;
+ }
+
+ public FieldDiffs setIssueKey(String issueKey) {
+ this.issueKey = issueKey;
+ return this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public FieldDiffs setDiff(String field, @Nullable Serializable oldValue, @Nullable Serializable newValue) {
+ Diff diff = diffs.get(field);
+ if (diff == null) {
+ diff = new Diff(oldValue, newValue);
+ diffs.put(field, diff);
+ } else {
+ diff.setNewValue(newValue);
+ }
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ boolean notFirst = false;
+ for (Map.Entry<String, Diff> entry : diffs.entrySet()) {
+ if (notFirst) {
+ sb.append(',');
+ } else {
+ notFirst = true;
+ }
+ sb.append(entry.getKey());
+ sb.append('=');
+ sb.append(entry.getValue().toString());
+ }
+ return sb.toString();
+ }
+
+ public static FieldDiffs parse(@Nullable String s) {
+ FieldDiffs diffs = new FieldDiffs();
+ if (!Strings.isNullOrEmpty(s)) {
+ Iterable<String> fields = FIELDS_SPLITTER.split(s);
+ for (String field : fields) {
+ String[] keyValues = field.split("=");
+ if (keyValues.length == 2) {
+ String[] values = keyValues[1].split("\\|");
+ String oldValue = "";
+ String newValue = "";
+ if(values.length == 1) {
+ newValue = Strings.nullToEmpty(values[0]);
+ } else if(values.length == 2) {
+ oldValue = Strings.nullToEmpty(values[0]);
+ newValue = Strings.nullToEmpty(values[1]);
+ }
+ diffs.setDiff(keyValues[0], oldValue, newValue);
+ } else {
+ diffs.setDiff(keyValues[0], "", "");
+ }
+ }
+ }
+ return diffs;
+ }
+
+ public static class Diff<T extends Serializable> implements Serializable {
+ private T oldValue;
+ private T newValue;
+
+ public Diff(@Nullable T oldValue, @Nullable T newValue) {
+ this.oldValue = oldValue;
+ this.newValue = newValue;
+ }
+
+ @CheckForNull
+ public T oldValue() {
+ return oldValue;
+ }
+
+ @CheckForNull
+ public Long oldValueLong() {
+ return toLong(oldValue);
+ }
+
+ @CheckForNull
+ public T newValue() {
+ return newValue;
+ }
+
+ @CheckForNull
+ public Long newValueLong() {
+ return toLong(newValue);
+ }
+
+ void setNewValue(T t) {
+ this.newValue = t;
+ }
+
+ @CheckForNull
+ private static Long toLong(@Nullable Serializable value) {
+ if (value != null && !"".equals(value)) {
+ try {
+ return Long.valueOf((String) value);
+ } catch (ClassCastException e) {
+ return (Long) value;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ //TODO escape , and | characters
+ StringBuilder sb = new StringBuilder();
+ if(newValue != null) {
+ if(oldValue != null) {
+ sb.append(oldValue.toString());
+ sb.append('|');
+ }
+ sb.append(newValue.toString());
+ }
+ return sb.toString();
+ }
+ }
+}
--- /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.
+ */
+package org.sonar.core.issue;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING.
+ *
+ * @since 3.6
+ */
+public class IssueChangeContext implements Serializable {
+
+ private final String login;
+ private final Date date;
+ private final boolean scan;
+
+ private IssueChangeContext(@Nullable String login, Date date, boolean scan) {
+ this.login = login;
+ this.date = date;
+ this.scan = scan;
+ }
+
+ @CheckForNull
+ public String login() {
+ return login;
+ }
+
+ public Date date() {
+ return date;
+ }
+
+ public boolean scan() {
+ return scan;
+ }
+
+ public static IssueChangeContext createScan(Date date) {
+ return new IssueChangeContext(null, date, true);
+ }
+
+ public static IssueChangeContext createUser(Date date, @Nullable String login) {
+ return new IssueChangeContext(login, date, false);
+ }
+}
import org.sonar.api.batch.BatchSide;
import org.sonar.api.server.ServerSide;
import org.sonar.api.issue.ActionPlan;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.IssueChangeContext;
import org.sonar.api.server.rule.RuleTagFormat;
import org.sonar.api.user.User;
import org.sonar.api.utils.Duration;
import javax.annotation.CheckForNull;
import org.apache.ibatis.session.ResultHandler;
import org.sonar.api.batch.BatchSide;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.server.ServerSide;
import org.sonar.core.persistence.DaoComponent;
import org.sonar.core.persistence.DbSession;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.utils.System2;
import javax.annotation.CheckForNull;
package org.sonar.core.issue.db;
-import javax.annotation.CheckForNull;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.SqlSession;
import org.sonar.api.batch.BatchSide;
this.mybatis = mybatis;
}
- @CheckForNull
- public IssueDto selectByKey(String key) {
- DbSession session = mybatis.openSession(false);
- try {
- return mapper(session).selectByKey(key);
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
public void selectNonClosedIssuesByModule(long componentId, ResultHandler handler) {
SqlSession session = mybatis.openSession(false);
try {
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
+import java.util.Set;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.Project;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.Duration;
return this;
}
- public Collection<String> getTags() {
+ public Set<String> getTags() {
return ImmutableSet.copyOf(TAGS_SPLITTER.split(tags == null ? "" : tags));
}
package org.sonar.core.issue.db;
import java.util.List;
+import java.util.Set;
public interface IssueMapper {
IssueDto selectByKey(String key);
+ List<IssueDto> selectOpenByComponentUuid(String componentUuid);
+
+ Set<String> selectComponentUuidsOfOpenIssuesForProjectUuid(String projectUuid);
+
List<IssueDto> selectByKeys(List<String> keys);
List<IssueDto> selectByActionPlan(String actionPlan);
int update(IssueDto issue);
int updateIfBeforeSelectedDate(IssueDto issue);
-
}
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.IssueComment;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.sonar.core.persistence.BatchSession;
package org.sonar.core.issue.db;
import com.google.common.annotations.VisibleForTesting;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.core.issue.DefaultIssue;
/**
* Support concurrent modifications on issues made by analysis and users at the same time
* See https://jira.sonarsource.com/browse/SONAR-4309
+ *
+ * TODO move to compute engine
*/
public class UpdateConflictResolver {
- private static final Logger LOG = LoggerFactory.getLogger(IssueStorage.class);
+ private static final Logger LOG = Loggers.get(UpdateConflictResolver.class);
public void resolve(DefaultIssue issue, IssueMapper mapper) {
LOG.debug("Resolve conflict on issue " + issue.key());
--- /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.
+ */
+package org.sonar.core.issue.tracking;
+
+import java.util.List;
+
+public class BlockHashSequence {
+
+ public static final int DEFAULT_HALF_BLOCK_SIZE = 5;
+ /**
+ * Hashes of blocks around lines. Line 1 is at index 0.
+ */
+ private final int[] blockHashes;
+
+ BlockHashSequence(LineHashSequence lineHashSequence, int halfBlockSize) {
+ this.blockHashes = new int[lineHashSequence.length()];
+
+ BlockHashFactory blockHashFactory = new BlockHashFactory(lineHashSequence.getHashes(), halfBlockSize);
+ for (int line = 1; line <= lineHashSequence.length(); line++) {
+ blockHashes[line - 1] = blockHashFactory.getHash();
+ if (line - halfBlockSize > 0) {
+ blockHashFactory.remove(lineHashSequence.getHashForLine(line - halfBlockSize).hashCode());
+ }
+ if (line + 1 + halfBlockSize <= lineHashSequence.length()) {
+ blockHashFactory.add(lineHashSequence.getHashForLine(line + 1 + halfBlockSize).hashCode());
+ } else {
+ blockHashFactory.add(0);
+ }
+ }
+ }
+
+ public static BlockHashSequence create(LineHashSequence lineHashSequence) {
+ return new BlockHashSequence(lineHashSequence, DEFAULT_HALF_BLOCK_SIZE);
+ }
+
+ /**
+ * Hash of block around line. Line must be in range of valid lines. It starts with 1.
+ */
+ public int getBlockHashForLine(int line) {
+ return blockHashes[line - 1];
+ }
+
+ private static class BlockHashFactory {
+ private static final int PRIME_BASE = 31;
+
+ private final int power;
+ private int hash = 0;
+
+ public BlockHashFactory(List<String> hashes, int halfBlockSize) {
+ int pow = 1;
+ for (int i = 0; i < halfBlockSize * 2; i++) {
+ pow = pow * PRIME_BASE;
+ }
+ this.power = pow;
+ for (int i = 1; i <= Math.min(hashes.size(), halfBlockSize + 1); i++) {
+ add(hashes.get(i - 1).hashCode());
+ }
+ }
+
+ public void add(int value) {
+ hash = hash * PRIME_BASE + value;
+ }
+
+ public void remove(int value) {
+ hash = hash - power * value;
+ }
+
+ public int getHash() {
+ return hash;
+ }
+
+ }
+}
--- /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.
+ */
+package org.sonar.core.issue.tracking;
+
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+class BlockRecognizer<RAW extends Trackable, BASE extends Trackable> {
+
+ /**
+ * If base source code is available, then detect code moves through block hashes.
+ * Only the issues associated to a line can be matched here.
+ */
+ void match(Input<RAW> rawInput, Input<BASE> baseInput, Tracking<RAW, BASE> tracking) {
+ BlockHashSequence baseHashSequence = baseInput.getBlockHashSequence();
+ BlockHashSequence rawHashSequence = rawInput.getBlockHashSequence();
+
+ Multimap<Integer, RAW> rawsByLine = groupByLine(tracking.getUnmatchedRaws());
+ Multimap<Integer, BASE> basesByLine = groupByLine(tracking.getUnmatchedBases());
+ Map<Integer, HashOccurrence> map = new HashMap<>();
+
+ for (Integer line : basesByLine.keySet()) {
+ int hash = baseHashSequence.getBlockHashForLine(line);
+ HashOccurrence hashOccurrence = map.get(hash);
+ if (hashOccurrence == null) {
+ // first occurrence in base
+ hashOccurrence = new HashOccurrence();
+ hashOccurrence.baseLine = line;
+ hashOccurrence.baseCount = 1;
+ map.put(hash, hashOccurrence);
+ } else {
+ hashOccurrence.baseCount++;
+ }
+ }
+
+ for (Integer line : rawsByLine.keySet()) {
+ int hash = rawHashSequence.getBlockHashForLine(line);
+ HashOccurrence hashOccurrence = map.get(hash);
+ if (hashOccurrence != null) {
+ hashOccurrence.rawLine = line;
+ hashOccurrence.rawCount++;
+ }
+ }
+
+ for (HashOccurrence hashOccurrence : map.values()) {
+ if (hashOccurrence.baseCount == 1 && hashOccurrence.rawCount == 1) {
+ // Guaranteed that baseLine has been moved to rawLine, so we can map all issues on baseLine to all issues on rawLine
+ map(rawsByLine.get(hashOccurrence.rawLine), basesByLine.get(hashOccurrence.baseLine), tracking);
+ basesByLine.removeAll(hashOccurrence.baseLine);
+ rawsByLine.removeAll(hashOccurrence.rawLine);
+ }
+ }
+
+ // Check if remaining number of lines exceeds threshold
+ if (basesByLine.keySet().size() * rawsByLine.keySet().size() < 250000) {
+ List<LinePair> possibleLinePairs = Lists.newArrayList();
+ for (Integer baseLine : basesByLine.keySet()) {
+ for (Integer rawLine : rawsByLine.keySet()) {
+ int weight = lengthOfMaximalBlock(baseInput.getLineHashSequence(), baseLine, rawInput.getLineHashSequence(), rawLine);
+ possibleLinePairs.add(new LinePair(baseLine, rawLine, weight));
+ }
+ }
+ Collections.sort(possibleLinePairs, LinePairComparator.INSTANCE);
+ for (LinePair linePair : possibleLinePairs) {
+ // High probability that baseLine has been moved to rawLine, so we can map all Issues on baseLine to all Issues on rawLine
+ map(rawsByLine.get(linePair.rawLine), basesByLine.get(linePair.baseLine), tracking);
+ }
+ }
+ }
+
+ /**
+ * @param startLineA number of line from first version of text (numbering starts from 1)
+ * @param startLineB number of line from second version of text (numbering starts from 1)
+ */
+ static int lengthOfMaximalBlock(LineHashSequence hashesA, int startLineA, LineHashSequence hashesB, int startLineB) {
+ if (!hashesA.getHashForLine(startLineA).equals(hashesB.getHashForLine(startLineB))) {
+ return 0;
+ }
+ int length = 0;
+ int ai = startLineA;
+ int bi = startLineB;
+ while (ai <= hashesA.length() && bi <= hashesB.length() && hashesA.getHashForLine(ai).equals(hashesB.getHashForLine(bi))) {
+ ai++;
+ bi++;
+ length++;
+ }
+ ai = startLineA;
+ bi = startLineB;
+ while (ai > 0 && bi > 0 && hashesA.getHashForLine(ai).equals(hashesB.getHashForLine(bi))) {
+ ai--;
+ bi--;
+ length++;
+ }
+ // Note that position (startA, startB) was counted twice
+ return length - 1;
+ }
+
+ private void map(Collection<RAW> raws, Collection<BASE> bases, Tracking<RAW, BASE> result) {
+ for (RAW raw : raws) {
+ for (BASE base : bases) {
+ if (result.containsUnmatchedBase(base) && base.getRuleKey().equals(raw.getRuleKey())) {
+ result.associateRawToBase(raw, base);
+ result.markRawAsAssociated(raw);
+ break;
+ }
+ }
+ }
+ }
+
+ private static <T extends Trackable> Multimap<Integer, T> groupByLine(Collection<T> trackables) {
+ Multimap<Integer, T> result = LinkedHashMultimap.create();
+ for (T trackable : trackables) {
+ Integer line = trackable.getLine();
+ if (line != null) {
+ result.put(line, trackable);
+ }
+ }
+ return result;
+ }
+
+ private static class LinePair {
+ int baseLine;
+ int rawLine;
+ int weight;
+
+ public LinePair(int baseLine, int rawLine, int weight) {
+ this.baseLine = baseLine;
+ this.rawLine = rawLine;
+ this.weight = weight;
+ }
+ }
+
+ private static class HashOccurrence {
+ int baseLine;
+ int rawLine;
+ int baseCount;
+ int rawCount;
+ }
+
+ private enum LinePairComparator implements Comparator<LinePair> {
+ INSTANCE;
+
+ @Override
+ public int compare(LinePair o1, LinePair o2) {
+ int weightDiff = o2.weight - o1.weight;
+ if (weightDiff != 0) {
+ return weightDiff;
+ } else {
+ return Math.abs(o1.baseLine - o1.rawLine) - Math.abs(o2.baseLine - o2.rawLine);
+ }
+ }
+ }
+}
--- /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.
+ */
+package org.sonar.core.issue.tracking;
+
+import java.util.Collection;
+
+public interface Input<ISSUE extends Trackable> {
+
+ LineHashSequence getLineHashSequence();
+ BlockHashSequence getBlockHashSequence();
+ Collection<ISSUE> getIssues();
+
+}
--- /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.
+ */
+package org.sonar.core.issue.tracking;
+
+import java.util.Collection;
+import java.util.List;
+
+public abstract class LazyInput<ISSUE extends Trackable> implements Input<ISSUE> {
+
+ private List<ISSUE> issues;
+ private LineHashSequence lineHashSeq;
+ private BlockHashSequence blockHashSeq;
+
+ @Override
+ public LineHashSequence getLineHashSequence() {
+ if (lineHashSeq == null) {
+ lineHashSeq = LineHashSequence.createForLines(loadSourceLines());
+ }
+ return lineHashSeq;
+ }
+
+ @Override
+ public BlockHashSequence getBlockHashSequence() {
+ if (blockHashSeq == null) {
+ blockHashSeq = BlockHashSequence.create(getLineHashSequence());
+ }
+ return blockHashSeq;
+ }
+
+ @Override
+ public Collection<ISSUE> getIssues() {
+ if (issues == null) {
+ issues = loadIssues();
+ }
+ return issues;
+ }
+
+ protected abstract Iterable<String> loadSourceLines();
+
+ protected abstract List<ISSUE> loadIssues();
+}
--- /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.
+ */
+package org.sonar.core.issue.tracking;
+
+import com.google.common.base.Strings;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Sequence of hash of lines for a given file
+ */
+public class LineHashSequence {
+
+ private static final int[] EMPTY_INTS = new int[0];
+
+ /**
+ * Hashes of lines. Line 1 is at index 0. No null elements.
+ */
+ private final List<String> hashes;
+ private final Map<String, int[]> linesByHash;
+
+ public LineHashSequence(List<String> hashes) {
+ this.hashes = hashes;
+ this.linesByHash = new HashMap<>(hashes.size());
+ for (int line = 1; line <= hashes.size(); line++) {
+ String hash = hashes.get(line - 1);
+ int[] lines = linesByHash.get(hash);
+ linesByHash.put(hash, appendLineTo(line, lines));
+ }
+ }
+
+ /**
+ * Number of lines
+ */
+ public int length() {
+ return hashes.size();
+ }
+
+ /**
+ * Checks if the line, starting with 1, is defined.
+ */
+ public boolean hasLine(int line) {
+ return 0 < line && line <= hashes.size();
+ }
+
+ /**
+ * The lines, starting with 1, that matches the given hash.
+ */
+ public int[] getLinesForHash(String hash) {
+ int[] lines = linesByHash.get(hash);
+ return lines == null ? EMPTY_INTS : lines;
+ }
+
+ /**
+ * Hash of the given line, which starts with 1. Return empty string
+ * is the line does not exist.
+ */
+ public String getHashForLine(int line) {
+ if (line > 0 && line <= hashes.size()) {
+ return Strings.nullToEmpty(hashes.get(line - 1));
+ }
+ return "";
+ }
+
+ List<String> getHashes() {
+ return hashes;
+ }
+
+ private static int[] appendLineTo(int line, @Nullable int[] to) {
+ int[] result;
+ if (to == null) {
+ result = new int[] {line};
+ } else {
+ result = new int[to.length + 1];
+ System.arraycopy(to, 0, result, 0, to.length);
+ result[result.length - 1] = line;
+ }
+ return result;
+ }
+
+ public static LineHashSequence createForLines(Iterable<String> lines) {
+ List<String> hashes = new ArrayList<>();
+ for (String line : lines) {
+ hashes.add(hash(line));
+ }
+ return new LineHashSequence(hashes);
+ }
+
+ // FIXME duplicates ComputeFileSourceData
+ private static String hash(String line) {
+ String reducedLine = StringUtils.replaceChars(line, "\t ", "");
+ if (reducedLine.isEmpty()) {
+ return "";
+ }
+ return DigestUtils.md5Hex(reducedLine);
+ }
+}
--- /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.
+ */
+package org.sonar.core.issue.tracking;
+
+import javax.annotation.CheckForNull;
+import org.sonar.api.rule.RuleKey;
+
+public interface Trackable {
+
+ /**
+ * The line index, starting with 1. Null means that
+ * issue does not relate to a line (file issue for example).
+ */
+ @CheckForNull
+ Integer getLine();
+
+ String getMessage();
+
+ @CheckForNull
+ String getLineHash();
+
+ RuleKey getRuleKey();
+}
--- /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.
+ */
+package org.sonar.core.issue.tracking;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Strings;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Objects;
+import javax.annotation.Nonnull;
+import org.sonar.api.rule.RuleKey;
+
+import static com.google.common.collect.FluentIterable.from;
+
+public class Tracker<RAW extends Trackable, BASE extends Trackable> {
+
+ public Tracking<RAW, BASE> track(Input<RAW> rawInput, Input<BASE> baseInput) {
+ Tracking<RAW, BASE> tracking = new Tracking<>(rawInput, baseInput);
+
+ // 1. match issues with same rule, same line and same line hash, but not necessarily with same message
+ match(tracking, LineAndLineHashKeyFactory.INSTANCE);
+
+ // 2. detect code moves by comparing blocks of codes
+ detectCodeMoves(rawInput, baseInput, tracking);
+
+ // 3. match issues with same rule, same message and same line hash
+ match(tracking, LineHashAndMessagekeyFactory.INSTANCE);
+
+ // 4. match issues with same rule, same line and same message
+ match(tracking, LineAndMessageKeyFactory.INSTANCE);
+
+ // 5. match issues with same rule and same line hash but different line and different message.
+ // See SONAR-2812
+ match(tracking, LineHashKeyFactory.INSTANCE);
+
+ // TODO what about issues on line 0 ?
+ relocateManualIssues(rawInput, tracking);
+
+ return tracking;
+ }
+
+ private void detectCodeMoves(Input<RAW> rawInput, Input<BASE> baseInput, Tracking<RAW, BASE> tracking) {
+ if (!tracking.isComplete()) {
+ new BlockRecognizer<RAW, BASE>().match(rawInput, baseInput, tracking);
+ }
+ }
+
+ private void match(Tracking<RAW, BASE> tracking, SearchKeyFactory factory) {
+ if (tracking.isComplete()) {
+ return;
+ }
+
+ Multimap<SearchKey, BASE> baseSearch = ArrayListMultimap.create();
+ for (BASE base : tracking.getUnmatchedBases()) {
+ baseSearch.put(factory.create(base), base);
+ }
+
+ Collection<RAW> trackedRaws = new ArrayList<>();
+ for (RAW raw : tracking.getUnmatchedRaws()) {
+ SearchKey rawKey = factory.create(raw);
+ Collection<BASE> bases = baseSearch.get(rawKey);
+ if (!bases.isEmpty()) {
+ // TODO taking the first one. Could be improved if there are more than 2 issues on the same line.
+ // Message could be checked to take the best one.
+ BASE match = bases.iterator().next();
+ tracking.associateRawToBase(raw, match);
+ baseSearch.remove(rawKey, match);
+ trackedRaws.add(raw);
+ }
+ }
+ tracking.markRawsAsAssociated(trackedRaws);
+ }
+
+ private void relocateManualIssues(Input<RAW> rawInput, Tracking<RAW, BASE> tracking) {
+ Iterable<BASE> manualIssues = from(tracking.getUnmatchedBases()).filter(IsManual.INSTANCE);
+ for (BASE base : manualIssues) {
+ if (base.getLine() == null) {
+ // no need to relocate. Location is unchanged.
+ tracking.associateManualIssueToLine(base, 0);
+ } else {
+ String lineHash = base.getLineHash();
+ if (!Strings.isNullOrEmpty(lineHash)) {
+ int[] rawLines = rawInput.getLineHashSequence().getLinesForHash(lineHash);
+ if (rawLines.length == 1) {
+ tracking.associateManualIssueToLine(base, rawLines[0]);
+ } else if (rawLines.length == 0 && base.getLine() <= rawInput.getLineHashSequence().length()) {
+ // still valid (???). We didn't manage to correctly detect code move, so the
+ // issue is kept at the same location, even if code changes
+ tracking.associateManualIssueToLine(base, base.getLine());
+ }
+ }
+ }
+ }
+ }
+
+ private enum IsManual implements Predicate<Trackable> {
+ INSTANCE;
+ @Override
+ public boolean apply(Trackable input) {
+ return input.getRuleKey().isManual();
+ }
+ }
+
+ private interface SearchKey {
+ }
+
+ private interface SearchKeyFactory {
+ SearchKey create(Trackable trackable);
+ }
+
+ private static class LineAndLineHashKey implements SearchKey {
+ private final RuleKey ruleKey;
+ private final String lineHash;
+ private final Integer line;
+
+ LineAndLineHashKey(Trackable trackable) {
+ this.ruleKey = trackable.getRuleKey();
+ this.line = trackable.getLine();
+ this.lineHash = trackable.getLineHash();
+ }
+
+ @Override
+ public boolean equals(@Nonnull Object o) {
+ if (this == o) {
+ return true;
+ }
+ LineAndLineHashKey that = (LineAndLineHashKey) o;
+ // start with most discriminant field
+ if (!Objects.equals(line, that.line)) {
+ return false;
+ }
+ if (!lineHash.equals(that.lineHash)) {
+ return false;
+ }
+ return ruleKey.equals(that.ruleKey);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = ruleKey.hashCode();
+ result = 31 * result + lineHash.hashCode();
+ result = 31 * result + (line != null ? line.hashCode() : 0);
+ return result;
+ }
+ }
+
+ private enum LineAndLineHashKeyFactory implements SearchKeyFactory {
+ INSTANCE;
+ @Override
+ public SearchKey create(Trackable t) {
+ return new LineAndLineHashKey(t);
+ }
+ }
+
+ private static class LineHashAndMessageKey implements SearchKey {
+ private final RuleKey ruleKey;
+ private final String message, lineHash;
+
+ LineHashAndMessageKey(Trackable trackable) {
+ this.ruleKey = trackable.getRuleKey();
+ this.message = trackable.getMessage();
+ this.lineHash = trackable.getLineHash();
+ }
+
+ @Override
+ public boolean equals(@Nonnull Object o) {
+ if (this == o) {
+ return true;
+ }
+ LineHashAndMessageKey that = (LineHashAndMessageKey) o;
+ // start with most discriminant field
+ if (!lineHash.equals(that.lineHash)) {
+ return false;
+ }
+ if (!message.equals(that.message)) {
+ return false;
+ }
+ return ruleKey.equals(that.ruleKey);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = ruleKey.hashCode();
+ result = 31 * result + message.hashCode();
+ result = 31 * result + lineHash.hashCode();
+ return result;
+ }
+ }
+
+ private enum LineHashAndMessagekeyFactory implements SearchKeyFactory {
+ INSTANCE;
+ @Override
+ public SearchKey create(Trackable t) {
+ return new LineHashAndMessageKey(t);
+ }
+ }
+
+ private static class LineAndMessageKey implements SearchKey {
+ private final RuleKey ruleKey;
+ private final String message;
+ private final Integer line;
+
+ LineAndMessageKey(Trackable trackable) {
+ this.ruleKey = trackable.getRuleKey();
+ this.message = trackable.getMessage();
+ this.line = trackable.getLine();
+ }
+
+ @Override
+ public boolean equals(@Nonnull Object o) {
+ if (this == o) {
+ return true;
+ }
+ LineAndMessageKey that = (LineAndMessageKey) o;
+ // start with most discriminant field
+ if (!Objects.equals(line, that.line)) {
+ return false;
+ }
+ if (!message.equals(that.message)) {
+ return false;
+ }
+ return ruleKey.equals(that.ruleKey);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = ruleKey.hashCode();
+ result = 31 * result + message.hashCode();
+ result = 31 * result + (line != null ? line.hashCode() : 0);
+ return result;
+ }
+ }
+
+ private enum LineAndMessageKeyFactory implements SearchKeyFactory {
+ INSTANCE;
+ @Override
+ public SearchKey create(Trackable t) {
+ return new LineAndMessageKey(t);
+ }
+ }
+
+ private static class LineHashKey implements SearchKey {
+ private final RuleKey ruleKey;
+ private final String lineHash;
+
+ LineHashKey(Trackable trackable) {
+ this.ruleKey = trackable.getRuleKey();
+ this.lineHash = trackable.getLineHash();
+ }
+
+ @Override
+ public boolean equals(@Nonnull Object o) {
+ if (this == o) {
+ return true;
+ }
+ LineAndLineHashKey that = (LineAndLineHashKey) o;
+ // start with most discriminant field
+ if (!lineHash.equals(that.lineHash)) {
+ return false;
+ }
+ return ruleKey.equals(that.ruleKey);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = ruleKey.hashCode();
+ result = 31 * result + lineHash.hashCode();
+ return result;
+ }
+ }
+
+ private enum LineHashKeyFactory implements SearchKeyFactory {
+ INSTANCE;
+ @Override
+ public SearchKey create(Trackable t) {
+ return new LineHashKey(t);
+ }
+ }
+}
--- /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.
+ */
+package org.sonar.core.issue.tracking;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.CheckForNull;
+
+public class Tracking<RAW extends Trackable, BASE extends Trackable> {
+
+ /**
+ * Tracked issues -> a raw issue is associated to a base issue
+ */
+ private final IdentityHashMap<RAW, BASE> rawToBase = new IdentityHashMap<>();
+
+ /**
+ * The raw issues that are not associated to a base issue.
+ */
+ private final Set<RAW> unmatchedRaws = Collections.newSetFromMap(new IdentityHashMap<RAW, Boolean>());
+
+ /**
+ * IdentityHashSet of the base issues that are not associated to a raw issue.
+ */
+ private final Set<BASE> unmatchedBases = Collections.newSetFromMap(new IdentityHashMap<BASE, Boolean>());
+
+ /**
+ * The manual issues that are still valid (related source code still exists). They
+ * are grouped by line. Lines start with 1. The key 0 references the manual
+ * issues that do not relate to a line.
+ */
+ private final Multimap<Integer, BASE> openManualIssues = ArrayListMultimap.create();
+
+ public Tracking(Input<RAW> rawInput, Input<BASE> baseInput) {
+ for (RAW raw : rawInput.getIssues()) {
+ // Extra verification if some plugins create issues on wrong lines
+ Integer rawLine = raw.getLine();
+ if (rawLine != null && !rawInput.getLineHashSequence().hasLine(rawLine)) {
+ throw new IllegalArgumentException("Issue line is not valid: " + raw);
+ }
+ this.unmatchedRaws.add(raw);
+ }
+ this.unmatchedBases.addAll(baseInput.getIssues());
+ }
+
+ public Set<RAW> getUnmatchedRaws() {
+ return unmatchedRaws;
+ }
+
+ public Map<RAW, BASE> getMatchedRaws() {
+ return rawToBase;
+ }
+
+ @CheckForNull
+ public BASE baseFor(RAW raw) {
+ return rawToBase.get(raw);
+ }
+
+ /**
+ * The base issues that are not matched by a raw issue and that need to be closed. Manual
+ */
+ public Set<BASE> getUnmatchedBases() {
+ return unmatchedBases;
+ }
+
+ boolean containsUnmatchedBase(BASE base) {
+ return unmatchedBases.contains(base);
+ }
+
+ void associateRawToBase(RAW raw, BASE base) {
+ rawToBase.put(raw, base);
+ unmatchedBases.remove(base);
+ }
+
+ void markRawAsAssociated(RAW raw) {
+ unmatchedRaws.remove(raw);
+ }
+
+ void markRawsAsAssociated(Collection<RAW> c) {
+ unmatchedRaws.removeAll(c);
+ }
+
+ boolean isComplete() {
+ return unmatchedRaws.isEmpty() || unmatchedBases.isEmpty();
+ }
+
+ public Multimap<Integer, BASE> getOpenManualIssuesByLine() {
+ return openManualIssues;
+ }
+
+ void associateManualIssueToLine(BASE manualIssue, int line) {
+ openManualIssues.put(line, manualIssue);
+ unmatchedBases.remove(manualIssue);
+ }
+}
--- /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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.core.issue.tracking;
+
+import javax.annotation.ParametersAreNonnullByDefault;
package org.sonar.core.issue.workflow;
import org.sonar.api.batch.BatchSide;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.api.server.ServerSide;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
import org.sonar.api.user.User;
import org.sonar.core.issue.IssueUpdater;
--- /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.
+ */
+package org.sonar.core.issue.workflow;
+
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.condition.Condition;
+import org.sonar.core.issue.DefaultIssue;
+
+enum IsBeingClosed implements Condition {
+ INSTANCE;
+
+ @Override
+ public boolean matches(Issue issue) {
+ return ((DefaultIssue) issue).isBeingClosed();
+ }
+}
+++ /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.
- */
-package org.sonar.core.issue.workflow;
-
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.condition.Condition;
-import org.sonar.api.issue.internal.DefaultIssue;
-
-class IsEndOfLife implements Condition {
-
- private final boolean endOfLife;
-
- IsEndOfLife(boolean endOfLife) {
- this.endOfLife = endOfLife;
- }
-
- @Override
- public boolean matches(Issue issue) {
- return ((DefaultIssue) issue).isEndOfLife() == endOfLife;
- }
-}
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.condition.Condition;
-class IsManual implements Condition {
-
- private final boolean manual;
-
- IsManual(boolean manual) {
- this.manual = manual;
- }
+enum IsManual implements Condition {
+ INSTANCE;
@Override
public boolean matches(Issue issue) {
- return manual==(issue.reporter()!=null);
+ return issue.ruleKey().isManual();
}
}
*/
package org.sonar.core.issue.workflow;
+import java.util.List;
import org.picocontainer.Startable;
import org.sonar.api.batch.BatchSide;
-import org.sonar.api.server.ServerSide;
import org.sonar.api.issue.DefaultTransitions;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.condition.HasResolution;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.api.issue.condition.NotCondition;
+import org.sonar.api.server.ServerSide;
import org.sonar.api.web.UserRole;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.issue.IssueUpdater;
-import java.util.List;
-
@BatchSide
@ServerSide
public class IssueWorkflow implements Startable {
.functions(new SetResolution(null))
.build())
.transition(Transition.builder(DefaultTransitions.REOPEN)
- .conditions(new IsManual(true))
+ .conditions(IsManual.INSTANCE)
.from(Issue.STATUS_CLOSED).to(Issue.STATUS_REOPENED)
.functions(new SetResolution(null), new SetCloseDate(false))
.build())
// resolve as false-positive
.transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE)
.from(Issue.STATUS_OPEN).to(Issue.STATUS_RESOLVED)
- .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE), SetAssignee.UNASSIGN)
+ .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE), UnsetAssignee.INSTANCE)
.requiredProjectPermission(UserRole.ISSUE_ADMIN)
.build())
.transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE)
.from(Issue.STATUS_REOPENED).to(Issue.STATUS_RESOLVED)
- .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE), SetAssignee.UNASSIGN)
+ .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE), UnsetAssignee.INSTANCE)
.requiredProjectPermission(UserRole.ISSUE_ADMIN)
.build())
.transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE)
.from(Issue.STATUS_CONFIRMED).to(Issue.STATUS_RESOLVED)
- .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE), SetAssignee.UNASSIGN)
+ .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE), UnsetAssignee.INSTANCE)
.requiredProjectPermission(UserRole.ISSUE_ADMIN)
.build())
// resolve as won't fix
.transition(Transition.builder(DefaultTransitions.WONT_FIX)
.from(Issue.STATUS_OPEN).to(Issue.STATUS_RESOLVED)
- .functions(new SetResolution(Issue.RESOLUTION_WONT_FIX), SetAssignee.UNASSIGN)
+ .functions(new SetResolution(Issue.RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE)
.requiredProjectPermission(UserRole.ISSUE_ADMIN)
.build())
.transition(Transition.builder(DefaultTransitions.WONT_FIX)
.from(Issue.STATUS_REOPENED).to(Issue.STATUS_RESOLVED)
- .functions(new SetResolution(Issue.RESOLUTION_WONT_FIX), SetAssignee.UNASSIGN)
+ .functions(new SetResolution(Issue.RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE)
.requiredProjectPermission(UserRole.ISSUE_ADMIN)
.build())
.transition(Transition.builder(DefaultTransitions.WONT_FIX)
.from(Issue.STATUS_CONFIRMED).to(Issue.STATUS_RESOLVED)
- .functions(new SetResolution(Issue.RESOLUTION_WONT_FIX), SetAssignee.UNASSIGN)
+ .functions(new SetResolution(Issue.RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE)
.requiredProjectPermission(UserRole.ISSUE_ADMIN)
.build()
);
private void buildAutomaticTransitions(StateMachine.Builder builder) {
// Close the "end of life" issues (disabled/deleted rule, deleted component)
- builder.transition(Transition.builder("automaticclose")
- .from(Issue.STATUS_OPEN).to(Issue.STATUS_CLOSED)
- .conditions(new IsEndOfLife(true))
- .functions(new SetEndOfLife(), new SetCloseDate(true))
- .automatic()
- .build())
+ builder
+ .transition(Transition.builder("automaticclose")
+ .from(Issue.STATUS_OPEN).to(Issue.STATUS_CLOSED)
+ .conditions(IsBeingClosed.INSTANCE)
+ .functions(SetClosed.INSTANCE, new SetCloseDate(true))
+ .automatic()
+ .build())
.transition(Transition.builder("automaticclose")
.from(Issue.STATUS_REOPENED).to(Issue.STATUS_CLOSED)
- .conditions(new IsEndOfLife(true))
- .functions(new SetEndOfLife(), new SetCloseDate(true))
+ .conditions(IsBeingClosed.INSTANCE)
+ .functions(SetClosed.INSTANCE, new SetCloseDate(true))
.automatic()
.build())
.transition(Transition.builder("automaticclose")
.from(Issue.STATUS_CONFIRMED).to(Issue.STATUS_CLOSED)
- .conditions(new IsEndOfLife(true))
- .functions(new SetEndOfLife(), new SetCloseDate(true))
+ .conditions(IsBeingClosed.INSTANCE)
+ .functions(SetClosed.INSTANCE, new SetCloseDate(true))
.automatic()
.build())
.transition(Transition.builder("automaticclose")
.from(Issue.STATUS_RESOLVED).to(Issue.STATUS_CLOSED)
- .conditions(new IsEndOfLife(true))
- .functions(new SetEndOfLife(), new SetCloseDate(true))
+ .conditions(IsBeingClosed.INSTANCE)
+ .functions(SetClosed.INSTANCE, new SetCloseDate(true))
.automatic()
.build())
.transition(Transition.builder("automaticclosemanual")
.from(Issue.STATUS_RESOLVED).to(Issue.STATUS_CLOSED)
- .conditions(new IsEndOfLife(false), new IsManual(true))
+ .conditions(new NotCondition(IsBeingClosed.INSTANCE), IsManual.INSTANCE)
.functions(new SetCloseDate(true))
.automatic()
.build())
// Manual issues are kept resolved.
.transition(Transition.builder("automaticreopen")
.from(Issue.STATUS_RESOLVED).to(Issue.STATUS_REOPENED)
- .conditions(new IsEndOfLife(false), new HasResolution(Issue.RESOLUTION_FIXED), new IsManual(false))
+ .conditions(new NotCondition(IsBeingClosed.INSTANCE), new HasResolution(Issue.RESOLUTION_FIXED), new NotCondition(IsManual.INSTANCE))
.functions(new SetResolution(null), new SetCloseDate(false))
.automatic()
.build()
+++ /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.
- */
-package org.sonar.core.issue.workflow;
-
-import org.sonar.api.user.User;
-
-import javax.annotation.Nullable;
-
-public class SetAssignee implements Function {
- public static final SetAssignee UNASSIGN = new SetAssignee(null);
-
- private final User assignee;
-
- public SetAssignee(@Nullable User assignee) {
- this.assignee = assignee;
- }
-
- @Override
- public void execute(Context context) {
- context.setAssignee(assignee);
- }
-}
*/
package org.sonar.core.issue.workflow;
-public class SetCloseDate implements Function {
+class SetCloseDate implements Function {
private final boolean set;
public SetCloseDate(boolean set) {
--- /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.
+ */
+package org.sonar.core.issue.workflow;
+
+import org.sonar.api.issue.Issue;
+import org.sonar.core.issue.DefaultIssue;
+
+public enum SetClosed implements Function {
+ INSTANCE;
+
+ @Override
+ public void execute(Context context) {
+ DefaultIssue issue = (DefaultIssue) context.issue();
+ if (!issue.isBeingClosed()) {
+ throw new IllegalStateException("Issue is still alive: " + issue);
+ }
+ if (issue.isOnDisabledRule()) {
+ context.setResolution(Issue.RESOLUTION_REMOVED);
+ } else {
+ context.setResolution(Issue.RESOLUTION_FIXED);
+ }
+
+ // closed issues are not "tracked" -> the line number does not evolve anymore
+ // when code changes. That's misleading for end-users, so line number
+ // is unset.
+ context.setLine(null);
+ }
+}
+++ /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.
- */
-package org.sonar.core.issue.workflow;
-
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-
-public class SetEndOfLife implements Function {
- @Override
- public void execute(Context context) {
- DefaultIssue issue = (DefaultIssue) context.issue();
- if (!issue.isEndOfLife()) {
- throw new IllegalStateException("Issue is still alive: " + issue);
- }
- if (issue.isOnDisabledRule()) {
- context.setResolution(Issue.RESOLUTION_REMOVED);
- } else {
- context.setResolution(Issue.RESOLUTION_FIXED);
- }
-
- // closed issues are not "tracked" -> the line number does not evolve anymore
- // when code changes. That's misleading for end-users, so line number
- // is unset.
- context.setLine(null);
- }
-}
--- /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.
+ */
+package org.sonar.core.issue.workflow;
+
+enum UnsetAssignee implements Function {
+ INSTANCE;
+
+ @Override
+ public void execute(Context context) {
+ context.setAssignee(null);
+ }
+}
--- /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.
+ */
+package org.sonar.core.issue.workflow;
+
+enum UnsetLine implements Function {
+ INSTANCE;
+ @Override
+ public void execute(Context context) {
+ context.setLine(null);
+ }
+
+}
where i.kee=#{kee}
</select>
- <select id="selectNonClosedIssuesByModule" parameterType="Long" resultType="Issue">
+ <select id="selectOpenByComponentUuid" parameterType="String" resultType="Issue">
+ select
+ i.id,
+ i.kee as kee,
+ i.rule_id as ruleId,
+ i.action_plan_key as actionPlanKey,
+ i.severity as severity,
+ i.manual_severity as manualSeverity,
+ i.message as message,
+ i.line as line,
+ i.effort_to_fix as effortToFix,
+ i.technical_debt as debt,
+ i.status as status,
+ i.resolution as resolution,
+ i.checksum as checksum,
+ i.reporter as reporter,
+ i.assignee as assignee,
+ i.author_login as authorLogin,
+ i.tags as tagsString,
+ i.issue_attributes as issueAttributes,
+ i.issue_creation_date as issueCreationTime,
+ i.issue_update_date as issueUpdateTime,
+ i.issue_close_date as issueCloseTime,
+ i.created_at as createdAt,
+ i.updated_at as updatedAt,
+ r.plugin_rule_key as ruleKey,
+ i.component_uuid as componentUuid,
+ i.project_uuid as projectUuid
+ from issues i
+ inner join rules r on r.id=i.rule_id
+ where
+ i.component_uuid=#{componentUuid} and
+ i.status <> 'CLOSED'
+ </select>
+
+ <select id="selectNonClosedIssuesByModule" parameterType="long" resultType="Issue">
select
i.id,
i.kee as kee,
where i.status <> 'CLOSED'
</select>
+ <select id="selectComponentUuidsOfOpenIssuesForProjectUuid" parameterType="string" resultType="string">
+ select distinct(i.component_uuid)
+ from issues i
+ where i.project_uuid=#{projectUuid} and i.status <> 'CLOSED'
+ </select>
+
<select id="selectByKeys" parameterType="map" resultType="Issue">
select
<include refid="issueColumns"/>
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
package org.sonar.core.issue;
import org.junit.Test;
-import org.sonar.api.issue.internal.IssueChangeContext;
import java.util.Date;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.issue.ActionPlan;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
-import org.sonar.api.issue.internal.IssueChangeContext;
import org.sonar.api.user.User;
import org.sonar.api.utils.Duration;
import org.sonar.core.user.DefaultUser;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.utils.DateUtils;
import org.sonar.core.persistence.AbstractDaoTestCase;
import org.sonar.core.persistence.DbSession;
package org.sonar.core.issue.db;
import org.junit.Test;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.utils.System2;
import static org.assertj.core.api.Assertions.assertThat;
session.close();
}
- @Test
- public void should_select_by_key() {
- setupData("shared", "should_select_by_key");
-
- IssueDto issue = dao.selectByKey("ABCDE");
- assertThat(issue.getKee()).isEqualTo("ABCDE");
- assertThat(issue.getId()).isEqualTo(100L);
- assertThat(issue.getRuleId()).isEqualTo(500);
- assertThat(issue.getSeverity()).isEqualTo("BLOCKER");
- assertThat(issue.isManualSeverity()).isFalse();
- assertThat(issue.getMessage()).isNull();
- assertThat(issue.getLine()).isEqualTo(200);
- assertThat(issue.getEffortToFix()).isEqualTo(4.2);
- assertThat(issue.getStatus()).isEqualTo("OPEN");
- assertThat(issue.getResolution()).isEqualTo("FIXED");
- assertThat(issue.getChecksum()).isEqualTo("XXX");
- assertThat(issue.getAuthorLogin()).isEqualTo("karadoc");
- assertThat(issue.getReporter()).isEqualTo("arthur");
- assertThat(issue.getAssignee()).isEqualTo("perceval");
- assertThat(issue.getIssueAttributes()).isEqualTo("JIRA=FOO-1234");
- assertThat(issue.getIssueCreationDate()).isNotNull();
- assertThat(issue.getIssueUpdateDate()).isNotNull();
- assertThat(issue.getIssueCloseDate()).isNotNull();
- assertThat(issue.getCreatedAt()).isNotNull();
- assertThat(issue.getUpdatedAt()).isNotNull();
- assertThat(issue.getRuleRepo()).isEqualTo("squid");
- assertThat(issue.getRule()).isEqualTo("AvoidCycle");
- assertThat(issue.getComponentUuid()).isEqualTo("CDEF");
- assertThat(issue.getComponentKey()).isEqualTo("Action.java");
- assertThat(issue.getModuleUuid()).isEqualTo("BCDE");
- assertThat(issue.getModuleUuidPath()).isEqualTo(".ABCD.BCDE.");
- assertThat(issue.getProjectKey()).isEqualTo("struts"); // ABCD
- assertThat(issue.getProjectUuid()).isEqualTo("ABCD"); // null
- }
-
@Test
public void select_non_closed_issues_by_module() {
setupData("shared", "should_select_non_closed_issues_by_module");
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.utils.Duration;
import org.sonar.core.rule.RuleDto;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.DefaultIssueComment;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.DefaultIssueComment;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.DateUtils;
--- /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.
+ */
+package org.sonar.core.issue.tracking;
+
+import org.junit.Test;
+
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class BlockHashSequenceTest {
+
+ @Test
+ public void test() {
+ BlockHashSequence a = new BlockHashSequence(LineHashSequence.createForLines(asList("line0", "line1", "line2")), 1);
+ BlockHashSequence b = new BlockHashSequence(LineHashSequence.createForLines(asList("line0", "line1", "line2", "line3")), 1);
+
+ assertThat(a.getBlockHashForLine(1)).isEqualTo(b.getBlockHashForLine(1));
+ assertThat(a.getBlockHashForLine(2)).isEqualTo(b.getBlockHashForLine(2));
+ assertThat(a.getBlockHashForLine(3)).isNotEqualTo(b.getBlockHashForLine(3));
+
+ BlockHashSequence c = new BlockHashSequence(LineHashSequence.createForLines(asList("line-1", "line0", "line1", "line2", "line3")), 1);
+ assertThat(a.getBlockHashForLine(1)).isNotEqualTo(c.getBlockHashForLine(2));
+ assertThat(a.getBlockHashForLine(2)).isEqualTo(c.getBlockHashForLine(3));
+ }
+}
--- /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.
+ */
+package org.sonar.core.issue.tracking;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class BlockRecognizerTest {
+
+ @Test
+ public void lengthOfMaximalBlock() {
+ /**
+ * - line 4 of first sequence is "d"
+ * - line 4 of second sequence is "d"
+ * - in each sequence, the 3 lines before and the line after are similar -> block size is 5
+ */
+ assertThat(compute(seq("abcde"), seq("abcde"), 4, 4)).isEqualTo(5);
+
+ assertThat(compute(seq("abcde"), seq("abcd"), 4, 4)).isEqualTo(4);
+ assertThat(compute(seq("bcde"), seq("abcde"), 4, 4)).isEqualTo(0);
+ assertThat(compute(seq("bcde"), seq("abcde"), 3, 4)).isEqualTo(4);
+ }
+
+ private int compute(LineHashSequence seqA, LineHashSequence seqB, int ai, int bi) {
+ return BlockRecognizer.lengthOfMaximalBlock(seqA, ai, seqB, bi);
+ }
+
+ private static LineHashSequence seq(String text) {
+ List<String> hashes = new ArrayList<>();
+ for (int i = 0; i < text.length(); i++) {
+ hashes.add("" + text.charAt(i));
+ }
+ return new LineHashSequence(hashes);
+ }
+
+}
--- /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.
+ */
+package org.sonar.core.issue.tracking;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.annotation.Nullable;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.rule.RuleKey;
+
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TrackerTest {
+
+ public static final RuleKey RULE_SYSTEM_PRINT = RuleKey.of("java", "SystemPrint");
+ public static final RuleKey RULE_UNUSED_LOCAL_VARIABLE = RuleKey.of("java", "UnusedLocalVariable");
+ public static final RuleKey RULE_UNUSED_PRIVATE_METHOD = RuleKey.of("java", "UnusedPrivateMethod");
+ public static final RuleKey RULE_NOT_DESIGNED_FOR_EXTENSION = RuleKey.of("java", "NotDesignedForExtension");
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ Tracker<Issue, Issue> tracker = new Tracker<>();
+
+ /**
+ * Of course rule must match
+ */
+ @Test
+ public void similar_issues_except_rule_do_not_match() {
+ FakeInput baseInput = new FakeInput("H1");
+ baseInput.createIssueOnLine(1, RULE_SYSTEM_PRINT, "msg");
+
+ FakeInput rawInput = new FakeInput("H1");
+ Issue raw = rawInput.createIssueOnLine(1, RULE_UNUSED_LOCAL_VARIABLE, "msg");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+ assertThat(tracking.baseFor(raw)).isNull();
+ }
+
+ @Test
+ @Ignore
+ public void different_issues_do_not_match() {
+ FakeInput baseInput = new FakeInput("H1");
+ Issue base = baseInput.createIssueOnLine(1, RULE_SYSTEM_PRINT, "msg1");
+
+ FakeInput rawInput = new FakeInput("H2", "H3", "H4", "H5", "H6");
+ Issue raw = rawInput.createIssueOnLine(5, RULE_SYSTEM_PRINT, "msg2");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+ assertThat(tracking.baseFor(raw)).isNull();
+ assertThat(tracking.getUnmatchedBases()).containsOnly(base);
+ }
+
+ @Test
+ public void line_hash_has_greater_priority_than_line() {
+ FakeInput baseInput = new FakeInput("H1", "H2", "H3");
+ Issue base1 = baseInput.createIssueOnLine(1, RULE_SYSTEM_PRINT, "msg");
+ Issue base2 = baseInput.createIssueOnLine(3, RULE_SYSTEM_PRINT, "msg");
+
+ FakeInput rawInput = new FakeInput("a", "b", "H1", "H2", "H3");
+ Issue raw1 = rawInput.createIssueOnLine(3, RULE_SYSTEM_PRINT, "msg");
+ Issue raw2 = rawInput.createIssueOnLine(5, RULE_SYSTEM_PRINT, "msg");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+ assertThat(tracking.baseFor(raw1)).isSameAs(base1);
+ assertThat(tracking.baseFor(raw2)).isSameAs(base2);
+ }
+
+ /**
+ * SONAR-2928
+ */
+ @Test
+ public void no_lines_and_different_messages_match() {
+ FakeInput baseInput = new FakeInput("H1", "H2", "H3");
+ Issue base = baseInput.createIssue(RULE_SYSTEM_PRINT, "msg1");
+
+ FakeInput rawInput = new FakeInput("H10", "H11", "H12");
+ Issue raw = rawInput.createIssue(RULE_SYSTEM_PRINT, "msg2");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+ assertThat(tracking.baseFor(raw)).isSameAs(base);
+ }
+
+ @Test
+ public void similar_issues_except_message_match() {
+ FakeInput baseInput = new FakeInput("H1");
+ Issue base = baseInput.createIssueOnLine(1, RULE_SYSTEM_PRINT, "msg1");
+
+ FakeInput rawInput = new FakeInput("H1");
+ Issue raw = rawInput.createIssueOnLine(1, RULE_SYSTEM_PRINT, "msg2");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+ assertThat(tracking.baseFor(raw)).isSameAs(base);
+ }
+
+ @Test
+ public void similar_issues_if_trimmed_messages_match() {
+ FakeInput baseInput = new FakeInput("H1");
+ Issue base = baseInput.createIssueOnLine(1, RULE_SYSTEM_PRINT, " message ");
+
+ FakeInput rawInput = new FakeInput("H2");
+ Issue raw = rawInput.createIssueOnLine(1, RULE_SYSTEM_PRINT, "message");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+ assertThat(tracking.baseFor(raw)).isSameAs(base);
+ }
+
+ /**
+ * Source code of this line was changed, but line and message still match
+ */
+ @Test
+ public void similar_issues_except_line_hash_match() {
+ FakeInput baseInput = new FakeInput("H1");
+ Issue base = baseInput.createIssueOnLine(1, RULE_SYSTEM_PRINT, "msg");
+
+ FakeInput rawInput = new FakeInput("H2");
+ Issue raw = rawInput.createIssueOnLine(1, RULE_SYSTEM_PRINT, "msg");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+ assertThat(tracking.baseFor(raw)).isSameAs(base);
+ }
+
+ @Test
+ public void similar_issues_except_line_match() {
+ FakeInput baseInput = new FakeInput("H1", "H2");
+ Issue base = baseInput.createIssueOnLine(1, RULE_SYSTEM_PRINT, "msg");
+
+ FakeInput rawInput = new FakeInput("H2", "H1");
+ Issue raw = rawInput.createIssueOnLine(2, RULE_SYSTEM_PRINT, "msg");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+ assertThat(tracking.baseFor(raw)).isSameAs(base);
+ }
+
+ /**
+ * SONAR-2812
+ */
+ @Test
+ public void only_same_line_hash_match_match() {
+ FakeInput baseInput = new FakeInput("H1", "H2");
+ Issue base = baseInput.createIssueOnLine(1, RULE_SYSTEM_PRINT, "msg");
+
+ FakeInput rawInput = new FakeInput("H3", "H4", "H1");
+ Issue raw = rawInput.createIssueOnLine(3, RULE_SYSTEM_PRINT, "other message");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+ assertThat(tracking.baseFor(raw)).isSameAs(base);
+ }
+
+ @Test
+ public void do_not_fail_if_base_issue_without_line() throws Exception {
+ FakeInput baseInput = new FakeInput("H1", "H2");
+ Issue base = baseInput.createIssueOnLine(1, RULE_SYSTEM_PRINT, "msg1");
+
+ FakeInput rawInput = new FakeInput("H3", "H4", "H5");
+ Issue raw = rawInput.createIssue(RULE_UNUSED_LOCAL_VARIABLE, "msg2");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+ assertThat(tracking.baseFor(raw)).isNull();
+ assertThat(tracking.getUnmatchedBases()).containsOnly(base);
+ }
+
+ @Test
+ public void do_not_fail_if_raw_issue_without_line() throws Exception {
+ FakeInput baseInput = new FakeInput("H1", "H2");
+ Issue base = baseInput.createIssue(RULE_SYSTEM_PRINT, "msg1");
+
+ FakeInput rawInput = new FakeInput("H3", "H4", "H5");
+ Issue raw = rawInput.createIssueOnLine(1, RULE_UNUSED_LOCAL_VARIABLE, "msg2");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+ assertThat(tracking.baseFor(raw)).isNull();
+ assertThat(tracking.getUnmatchedBases()).containsOnly(base);
+ }
+
+ @Test
+ public void fail_if_raw_line_does_not_exist() throws Exception {
+ FakeInput baseInput = new FakeInput();
+ FakeInput rawInput = new FakeInput("H1").addIssue(new Issue(200, "H200", RULE_SYSTEM_PRINT, "msg"));
+
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Issue line is not valid");
+ tracker.track(rawInput, baseInput);
+ }
+
+ /**
+ * SONAR-3072
+ */
+ @Test
+ public void recognize_blocks_1() throws Exception {
+ FakeInput baseInput = FakeInput.createForSourceLines(
+ "package example1;",
+ "",
+ "public class Toto {",
+ "",
+ " public void doSomething() {",
+ " // doSomething",
+ " }",
+ "",
+ " public void doSomethingElse() {",
+ " // doSomethingElse",
+ " }",
+ "}"
+ );
+ Issue base1 = baseInput.createIssueOnLine(7, RULE_SYSTEM_PRINT, "Indentation");
+ Issue base2 = baseInput.createIssueOnLine(11, RULE_SYSTEM_PRINT, "Indentation");
+
+ FakeInput rawInput = FakeInput.createForSourceLines(
+ "package example1;",
+ "",
+ "public class Toto {",
+ "",
+ " public Toto(){}",
+ "",
+ " public void doSomethingNew() {",
+ " // doSomethingNew",
+ " }",
+ "",
+ " public void doSomethingElseNew() {",
+ " // doSomethingElseNew",
+ " }",
+ "",
+ " public void doSomething() {",
+ " // doSomething",
+ " }",
+ "",
+ " public void doSomethingElse() {",
+ " // doSomethingElse",
+ " }",
+ "}"
+ );
+ Issue raw1 = rawInput.createIssueOnLine(9, RULE_SYSTEM_PRINT, "Indentation");
+ Issue raw2 = rawInput.createIssueOnLine(13, RULE_SYSTEM_PRINT, "Indentation");
+ Issue raw3 = rawInput.createIssueOnLine(17, RULE_SYSTEM_PRINT, "Indentation");
+ Issue raw4 = rawInput.createIssueOnLine(21, RULE_SYSTEM_PRINT, "Indentation");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+ assertThat(tracking.baseFor(raw1)).isNull();
+ assertThat(tracking.baseFor(raw2)).isNull();
+ assertThat(tracking.baseFor(raw3)).isSameAs(base1);
+ assertThat(tracking.baseFor(raw4)).isSameAs(base2);
+ assertThat(tracking.getUnmatchedBases()).isEmpty();
+ }
+
+ /**
+ * SONAR-3072
+ */
+ @Test
+ public void recognize_blocks_2() throws Exception {
+ FakeInput baseInput = FakeInput.createForSourceLines(
+ "package example2;",
+ "",
+ "public class Toto {",
+ " void method1() {",
+ " System.out.println(\"toto\");",
+ " }",
+ "}"
+ );
+ Issue base1 = baseInput.createIssueOnLine(5, RULE_SYSTEM_PRINT, "SystemPrintln");
+
+ FakeInput rawInput = FakeInput.createForSourceLines(
+ "package example2;",
+ "",
+ "public class Toto {",
+ "",
+ " void method2() {",
+ " System.out.println(\"toto\");",
+ " }",
+ "",
+ " void method1() {",
+ " System.out.println(\"toto\");",
+ " }",
+ "",
+ " void method3() {",
+ " System.out.println(\"toto\");",
+ " }",
+ "}"
+ );
+ Issue raw1 = rawInput.createIssueOnLine(6, RULE_SYSTEM_PRINT, "SystemPrintln");
+ Issue raw2 = rawInput.createIssueOnLine(10, RULE_SYSTEM_PRINT, "SystemPrintln");
+ Issue raw3 = rawInput.createIssueOnLine(14, RULE_SYSTEM_PRINT, "SystemPrintln");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+ assertThat(tracking.baseFor(raw1)).isNull();
+ assertThat(tracking.baseFor(raw2)).isSameAs(base1);
+ assertThat(tracking.baseFor(raw3)).isNull();
+ }
+
+ @Test
+ public void recognize_blocks_3() throws Exception {
+ FakeInput baseInput = FakeInput.createForSourceLines(
+ "package sample;",
+ "",
+ "public class Sample {",
+ "\t",
+ "\tpublic Sample(int i) {",
+ "\t\tint j = i+1;", // UnusedLocalVariable
+ "\t}",
+ "",
+ "\tpublic boolean avoidUtilityClass() {", // NotDesignedForExtension
+ "\t\treturn true;",
+ "\t}",
+ "",
+ "\tprivate String myMethod() {", // UnusedPrivateMethod
+ "\t\treturn \"hello\";",
+ "\t}",
+ "}"
+ );
+ Issue base1 = baseInput.createIssueOnLine(6, RULE_UNUSED_LOCAL_VARIABLE, "Avoid unused local variables such as 'j'.");
+ Issue base2 = baseInput.createIssueOnLine(13, RULE_UNUSED_PRIVATE_METHOD, "Avoid unused private methods such as 'myMethod()'.");
+ Issue base3 = baseInput.createIssueOnLine(9, RULE_NOT_DESIGNED_FOR_EXTENSION,
+ "Method 'avoidUtilityClass' is not designed for extension - needs to be abstract, final or empty.");
+
+ FakeInput rawInput = FakeInput.createForSourceLines(
+ "package sample;",
+ "",
+ "public class Sample {",
+ "",
+ "\tpublic Sample(int i) {",
+ "\t\tint j = i+1;", // UnusedLocalVariable is still there
+ "\t}",
+ "\t",
+ "\tpublic boolean avoidUtilityClass() {", // NotDesignedForExtension is still there
+ "\t\treturn true;",
+ "\t}",
+ "\t",
+ "\tprivate String myMethod() {", // issue UnusedPrivateMethod is fixed because it's called at line 18
+ "\t\treturn \"hello\";",
+ "\t}",
+ "",
+ " public void newIssue() {",
+ " String msg = myMethod();", // new issue UnusedLocalVariable
+ " }",
+ "}"
+ );
+
+ Issue newRaw = rawInput.createIssueOnLine(18, RULE_UNUSED_LOCAL_VARIABLE, "Avoid unused local variables such as 'msg'.");
+ Issue rawSameAsBase1 = rawInput.createIssueOnLine(6, RULE_UNUSED_LOCAL_VARIABLE, "Avoid unused local variables such as 'j'.");
+ Issue rawSameAsBase3 = rawInput.createIssueOnLine(9, RULE_NOT_DESIGNED_FOR_EXTENSION,
+ "Method 'avoidUtilityClass' is not designed for extension - needs to be abstract, final or empty.");
+
+ Tracking<Issue, Issue> tracking = tracker.track(rawInput, baseInput);
+
+ assertThat(tracking.baseFor(newRaw)).isNull();
+ assertThat(tracking.baseFor(rawSameAsBase1)).isSameAs(base1);
+ assertThat(tracking.baseFor(rawSameAsBase3)).isSameAs(base3);
+ assertThat(tracking.getUnmatchedBases()).containsOnly(base2);
+ }
+
+ private static class Issue implements Trackable {
+ private final RuleKey ruleKey;
+ private final Integer line;
+ private final String message, lineHash;
+
+ Issue(@Nullable Integer line, String lineHash, RuleKey ruleKey, String message) {
+ this.line = line;
+ this.lineHash = lineHash;
+ this.ruleKey = ruleKey;
+ this.message = message;
+ }
+
+ @Override
+ public Integer getLine() {
+ return line;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+
+ @Override
+ public String getLineHash() {
+ return lineHash;
+ }
+
+ @Override
+ public RuleKey getRuleKey() {
+ return ruleKey;
+ }
+ }
+
+ private static class FakeInput implements Input<Issue> {
+ private final List<Issue> issues = new ArrayList<>();
+ private final List<String> lineHashes;
+
+ public FakeInput(String... lineHashes) {
+ this.lineHashes = asList(lineHashes);
+ }
+
+ static FakeInput createForSourceLines(String... lines) {
+ String[] hashes = new String[lines.length];
+ for (int i = 0; i < lines.length; i++) {
+ hashes[i] = DigestUtils.md5Hex(lines[i].replaceAll("[\t ]", ""));
+ }
+ return new FakeInput(hashes);
+ }
+
+ public Issue createIssueOnLine(int line, RuleKey ruleKey, String message) {
+ Issue issue = new Issue(line, lineHashes.get(line - 1), ruleKey, message);
+ issues.add(issue);
+ return issue;
+ }
+
+ /**
+ * No line (line 0)
+ */
+ public Issue createIssue(RuleKey ruleKey, String message) {
+ Issue issue = new Issue(null, "", ruleKey, message);
+ issues.add(issue);
+ return issue;
+ }
+
+ public FakeInput addIssue(Issue issue) {
+ this.issues.add(issue);
+ return this;
+ }
+
+ @Override
+ public LineHashSequence getLineHashSequence() {
+ return new LineHashSequence(lineHashes);
+ }
+
+ @Override
+ public BlockHashSequence getBlockHashSequence() {
+ return new BlockHashSequence(getLineHashSequence(), 2);
+ }
+
+ @Override
+ public Collection<Issue> getIssues() {
+ return issues;
+ }
+ }
+}
--- /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.
+ */
+package org.sonar.core.issue.workflow;
+
+import org.junit.Test;
+import org.sonar.core.issue.DefaultIssue;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.core.issue.workflow.IsBeingClosed.INSTANCE;
+
+public class IsBeingClosedTest {
+
+
+ @Test
+ public void should_be_end_of_life() {
+ DefaultIssue issue = new DefaultIssue();
+ assertThat(INSTANCE.matches(issue.setBeingClosed(true))).isTrue();
+ assertThat(INSTANCE.matches(issue.setBeingClosed(false))).isFalse();
+ }
+
+}
+++ /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.
- */
-package org.sonar.core.issue.workflow;
-
-import org.junit.Test;
-import org.sonar.api.issue.internal.DefaultIssue;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class IsEndOfLifeTest {
- DefaultIssue issue = new DefaultIssue();
-
- @Test
- public void should_be_end_of_life() {
- IsEndOfLife condition = new IsEndOfLife(true);
- assertThat(condition.matches(issue.setEndOfLife(true))).isTrue();
- assertThat(condition.matches(issue.setEndOfLife(false))).isFalse();
- }
-
- @Test
- public void should_not_be_end_of_life() {
- IsEndOfLife condition = new IsEndOfLife(false);
- assertThat(condition.matches(issue.setEndOfLife(true))).isFalse();
- assertThat(condition.matches(issue.setEndOfLife(false))).isTrue();
- }
-}
package org.sonar.core.issue.workflow;
import org.junit.Test;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.core.issue.DefaultIssue;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.core.issue.workflow.IsManual.INSTANCE;
public class IsManualTest {
- DefaultIssue issue = new DefaultIssue();
@Test
public void should_match() {
- IsManual condition = new IsManual(true);
- assertThat(condition.matches(issue.setReporter("you"))).isTrue();
- assertThat(condition.matches(issue.setReporter(null))).isFalse();
+ DefaultIssue issue = new DefaultIssue();
+ assertThat(INSTANCE.matches(issue.setRuleKey(RuleKey.of(RuleKey.MANUAL_REPOSITORY_KEY, "R1")))).isTrue();
+ assertThat(INSTANCE.matches(issue.setRuleKey(RuleKey.of("java", "R1")))).isFalse();
}
- @Test
- public void should_match_dead() {
- IsManual condition = new IsManual(false);
- assertThat(condition.matches(issue.setReporter("you"))).isFalse();
- assertThat(condition.matches(issue.setReporter(null))).isTrue();
- }
}
import org.junit.Test;
import org.sonar.api.issue.DefaultTransitions;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.api.rule.RuleKey;
import org.sonar.core.issue.IssueUpdater;
public void list_no_out_transition_from_status_closed() {
workflow.start();
- DefaultIssue issue = new DefaultIssue().setStatus(Issue.STATUS_CLOSED);
+ DefaultIssue issue = new DefaultIssue().setStatus(Issue.STATUS_CLOSED).setRuleKey(RuleKey.of("java", "R1 "));
List<Transition> transitions = workflow.outTransitions(issue);
assertThat(transitions).isEmpty();
}
.setResolution(Issue.RESOLUTION_FIXED)
.setStatus(Issue.STATUS_RESOLVED)
.setNew(false)
- .setEndOfLife(true);
+ .setBeingClosed(true);
Date now = new Date();
workflow.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
assertThat(issue.resolution()).isEqualTo(Issue.RESOLUTION_FIXED);
.setResolution(null)
.setStatus(Issue.STATUS_OPEN)
.setNew(false)
- .setEndOfLife(true);
+ .setBeingClosed(true);
Date now = new Date();
workflow.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
assertThat(issue.resolution()).isEqualTo(Issue.RESOLUTION_FIXED);
.setResolution(null)
.setStatus(Issue.STATUS_REOPENED)
.setNew(false)
- .setEndOfLife(true);
+ .setBeingClosed(true);
Date now = new Date();
workflow.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
assertThat(issue.resolution()).isEqualTo(Issue.RESOLUTION_FIXED);
.setResolution(null)
.setStatus(Issue.STATUS_CONFIRMED)
.setNew(false)
- .setEndOfLife(true);
+ .setBeingClosed(true);
Date now = new Date();
workflow.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
assertThat(issue.resolution()).isEqualTo(Issue.RESOLUTION_FIXED);
.setResolution(Issue.RESOLUTION_FIXED)
.setStatus("xxx")
.setNew(false)
- .setEndOfLife(true);
+ .setBeingClosed(true);
try {
workflow.doAutomaticTransition(issue, IssueChangeContext.createScan(new Date()));
fail();
.setStatus(Issue.STATUS_OPEN)
.setRuleKey(RuleKey.of("manual", "Performance"))
.setReporter("simon")
- .setEndOfLife(true)
+ .setBeingClosed(true)
.setOnDisabledRule(true);
workflow.start();
.setStatus(Issue.STATUS_OPEN)
.setRuleKey(RuleKey.of("manual", "Performance"))
.setReporter("simon")
- .setEndOfLife(true)
+ .setBeingClosed(true)
.setOnDisabledRule(false);
workflow.start();
+++ /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.
- */
-
-package org.sonar.core.issue.workflow;
-
-import org.junit.Test;
-import org.sonar.api.user.User;
-import org.sonar.core.user.DefaultUser;
-
-import static org.mockito.Mockito.*;
-
-public class SetAssigneeTest {
- @Test
- public void assign() {
- User user = new DefaultUser().setLogin("eric").setName("eric");
- SetAssignee function = new SetAssignee(user);
- Function.Context context = mock(Function.Context.class);
- function.execute(context);
- verify(context, times(1)).setAssignee(user);
- }
-
- @Test
- public void unassign() {
- Function.Context context = mock(Function.Context.class);
- SetAssignee.UNASSIGN.execute(context);
- verify(context, times(1)).setAssignee(null);
- }
-}
--- /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.
+ */
+package org.sonar.core.issue.workflow;
+
+import org.junit.Test;
+import org.sonar.api.issue.Issue;
+import org.sonar.core.issue.DefaultIssue;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.*;
+import static org.sonar.core.issue.workflow.SetClosed.INSTANCE;
+
+public class SetClosedTest {
+
+ Function.Context context = mock(Function.Context.class);
+
+ @Test
+ public void should_resolve_as_fixed() {
+ Issue issue = new DefaultIssue().setBeingClosed(true).setOnDisabledRule(false);
+ when(context.issue()).thenReturn(issue);
+ INSTANCE.execute(context);
+ verify(context, times(1)).setResolution(Issue.RESOLUTION_FIXED);
+ }
+
+ @Test
+ public void should_resolve_as_removed_when_rule_is_disabled() {
+ Issue issue = new DefaultIssue().setBeingClosed(true).setOnDisabledRule(true);
+ when(context.issue()).thenReturn(issue);
+ INSTANCE.execute(context);
+ verify(context, times(1)).setResolution(Issue.RESOLUTION_REMOVED);
+ }
+
+ @Test
+ public void should_fail_if_issue_is_not_resolved() {
+ Issue issue = new DefaultIssue().setBeingClosed(false);
+ when(context.issue()).thenReturn(issue);
+ try {
+ INSTANCE.execute(context);
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e.getMessage()).contains("Issue is still alive");
+ verify(context, never()).setResolution(anyString());
+ }
+ }
+
+ @Test
+ public void line_number_must_be_unset() {
+ Issue issue = new DefaultIssue().setBeingClosed(true).setLine(10);
+ when(context.issue()).thenReturn(issue);
+ INSTANCE.execute(context);
+ verify(context).setLine(null);
+ }
+}
+++ /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.
- */
-package org.sonar.core.issue.workflow;
-
-import org.junit.Test;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.*;
-
-public class SetEndOfLifeTest {
-
- Function.Context context = mock(Function.Context.class);
- SetEndOfLife function = new SetEndOfLife();
-
- @Test
- public void should_resolve_as_fixed() {
- Issue issue = new DefaultIssue().setEndOfLife(true).setOnDisabledRule(false);
- when(context.issue()).thenReturn(issue);
- function.execute(context);
- verify(context, times(1)).setResolution(Issue.RESOLUTION_FIXED);
- }
-
- @Test
- public void should_resolve_as_removed_when_rule_is_disabled() {
- Issue issue = new DefaultIssue().setEndOfLife(true).setOnDisabledRule(true);
- when(context.issue()).thenReturn(issue);
- function.execute(context);
- verify(context, times(1)).setResolution(Issue.RESOLUTION_REMOVED);
- }
-
- @Test
- public void should_fail_if_issue_is_not_resolved() {
- Issue issue = new DefaultIssue().setEndOfLife(false);
- when(context.issue()).thenReturn(issue);
- try {
- function.execute(context);
- fail();
- } catch (IllegalStateException e) {
- assertThat(e.getMessage()).contains("Issue is still alive");
- verify(context, never()).setResolution(anyString());
- }
- }
-
- @Test
- public void line_number_must_be_unset() {
- Issue issue = new DefaultIssue().setEndOfLife(true).setLine(10);
- when(context.issue()).thenReturn(issue);
- function.execute(context);
- verify(context).setLine(null);
- }
-}
import org.junit.Test;
import org.sonar.api.issue.condition.Condition;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
--- /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.
+ */
+
+package org.sonar.core.issue.workflow;
+
+import org.junit.Test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.sonar.core.issue.workflow.UnsetAssignee.INSTANCE;
+
+public class UnsetAssigneeTest {
+
+ @Test
+ public void unassign() {
+ Function.Context context = mock(Function.Context.class);
+ INSTANCE.execute(context);
+ verify(context, times(1)).setAssignee(null);
+ }
+}
+++ /dev/null
-<dataset>
-
- <issues
- id="100"
- kee="ABCDE"
- component_uuid="CDEF"
- project_uuid="ABCD"
- rule_id="500"
- severity="BLOCKER"
- manual_severity="[false]"
- message="[null]"
- line="200"
- effort_to_fix="4.2"
- status="OPEN"
- resolution="FIXED"
- checksum="XXX"
- reporter="arthur"
- assignee="perceval"
- author_login="karadoc"
- issue_attributes="JIRA=FOO-1234"
- issue_creation_date="1366063200000"
- issue_update_date="1366063200000"
- issue_close_date="1366063200000"
- created_at="1400000000000"
- updated_at="1400000000000"
- />
-
-</dataset>
package org.sonar.api.issue;
import com.google.common.collect.ImmutableList;
-import org.sonar.api.batch.BatchSide;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.utils.Duration;
-
-import javax.annotation.CheckForNull;
-
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
+import javax.annotation.CheckForNull;
+import org.sonar.api.batch.BatchSide;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.utils.Duration;
/**
* @since 3.6
+++ /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.
- */
-package org.sonar.api.issue.internal;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.commons.lang.builder.ToStringStyle;
-import org.apache.commons.lang.time.DateUtils;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueComment;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.Severity;
-import org.sonar.api.utils.Duration;
-
-/**
- * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING.
- *
- * @since 3.6
- */
-public class DefaultIssue implements Issue {
-
- private String key;
-
- private String componentUuid;
- private String componentKey;
-
- private String moduleUuid;
- private String moduleUuidPath;
-
- private String projectUuid;
- private String projectKey;
-
- private RuleKey ruleKey;
- private String language;
- private String severity;
- private boolean manualSeverity = false;
- private String message;
- private Integer line;
- private Double effortToFix;
- private Duration debt;
- private String status;
- private String resolution;
- private String reporter;
- private String assignee;
- private String checksum;
- private Map<String, String> attributes = null;
- private String authorLogin = null;
- private String actionPlanKey;
- private List<IssueComment> comments = null;
- private Set<String> tags = null;
-
- // FUNCTIONAL DATES
- private Date creationDate;
- private Date updateDate;
- private Date closeDate;
-
- // FOLLOWING FIELDS ARE AVAILABLE ONLY DURING SCAN
-
- // Current changes
- private FieldDiffs currentChange = null;
-
- // all changes
- private List<FieldDiffs> changes = null;
-
- // true if the the issue did not exist in the previous scan.
- private boolean isNew = true;
-
- // True if the the issue did exist in the previous scan but not in the current one. That means
- // that this issue should be closed.
- private boolean endOfLife = false;
-
- private boolean onDisabledRule = false;
-
- // true if some fields have been changed since the previous scan
- private boolean isChanged = false;
-
- // true if notifications have to be sent
- private boolean sendNotifications = false;
-
- // Date when issue was loaded from db (only when isNew=false)
- private Long selectedAt;
-
- @Override
- public String key() {
- return key;
- }
-
- public DefaultIssue setKey(String key) {
- this.key = key;
- return this;
- }
-
- /**
- * Can be null on Views or Devs
- */
- @Override
- @CheckForNull
- public String componentUuid() {
- return componentUuid;
- }
-
- public DefaultIssue setComponentUuid(@CheckForNull String componentUuid) {
- this.componentUuid = componentUuid;
- return this;
- }
-
- @Override
- public String componentKey() {
- return componentKey;
- }
-
- public DefaultIssue setComponentKey(String s) {
- this.componentKey = s;
- return this;
- }
-
- @CheckForNull
- public String moduleUuid() {
- return moduleUuid;
- }
-
- public DefaultIssue setModuleUuid(@Nullable String moduleUuid) {
- this.moduleUuid = moduleUuid;
- return this;
- }
-
- @CheckForNull
- public String moduleUuidPath() {
- return moduleUuidPath;
- }
-
- public DefaultIssue setModuleUuidPath(@Nullable String moduleUuidPath) {
- this.moduleUuidPath = moduleUuidPath;
- return this;
- }
-
- /**
- * Can be null on Views or Devs
- */
- @Override
- @CheckForNull
- public String projectUuid() {
- return projectUuid;
- }
-
- public DefaultIssue setProjectUuid(@Nullable String projectUuid) {
- this.projectUuid = projectUuid;
- return this;
- }
-
- @Override
- public String projectKey() {
- return projectKey;
- }
-
- public DefaultIssue setProjectKey(String projectKey) {
- this.projectKey = projectKey;
- return this;
- }
-
- @Override
- public RuleKey ruleKey() {
- return ruleKey;
- }
-
- public DefaultIssue setRuleKey(RuleKey k) {
- this.ruleKey = k;
- return this;
- }
-
- @Override
- public String language() {
- return language;
- }
-
- public DefaultIssue setLanguage(String l) {
- this.language = l;
- return this;
- }
-
- @Override
- public String severity() {
- return severity;
- }
-
- public DefaultIssue setSeverity(@Nullable String s) {
- Preconditions.checkArgument(s == null || Severity.ALL.contains(s), "Not a valid severity: " + s);
- this.severity = s;
- return this;
- }
-
- public boolean manualSeverity() {
- return manualSeverity;
- }
-
- public DefaultIssue setManualSeverity(boolean b) {
- this.manualSeverity = b;
- return this;
- }
-
- @Override
- @CheckForNull
- public String message() {
- return message;
- }
-
- public DefaultIssue setMessage(@Nullable String s) {
- this.message = StringUtils.abbreviate(StringUtils.trim(s), MESSAGE_MAX_SIZE);
- return this;
- }
-
- @Override
- @CheckForNull
- public Integer line() {
- return line;
- }
-
- public DefaultIssue setLine(@Nullable Integer l) {
- Preconditions.checkArgument(l == null || l > 0, "Line must be null or greater than zero (got " + l + ")");
- this.line = l;
- return this;
- }
-
- @Override
- @CheckForNull
- public Double effortToFix() {
- return effortToFix;
- }
-
- public DefaultIssue setEffortToFix(@Nullable Double d) {
- Preconditions.checkArgument(d == null || d >= 0, "Effort to fix must be greater than or equal 0 (got " + d + ")");
- this.effortToFix = d;
- return this;
- }
-
- /**
- * Elapsed time to fix the issue
- */
- @Override
- @CheckForNull
- public Duration debt() {
- return debt;
- }
-
- @CheckForNull
- public Long debtInMinutes() {
- return debt != null ? debt.toMinutes() : null;
- }
-
- public DefaultIssue setDebt(@Nullable Duration t) {
- this.debt = t;
- return this;
- }
-
- @Override
- public String status() {
- return status;
- }
-
- public DefaultIssue setStatus(String s) {
- Preconditions.checkArgument(!Strings.isNullOrEmpty(s), "Status must be set");
- this.status = s;
- return this;
- }
-
- @Override
- @CheckForNull
- public String resolution() {
- return resolution;
- }
-
- public DefaultIssue setResolution(@Nullable String s) {
- this.resolution = s;
- return this;
- }
-
- @Override
- @CheckForNull
- public String reporter() {
- return reporter;
- }
-
- public DefaultIssue setReporter(@Nullable String s) {
- this.reporter = s;
- return this;
- }
-
- @Override
- @CheckForNull
- public String assignee() {
- return assignee;
- }
-
- public DefaultIssue setAssignee(@Nullable String s) {
- this.assignee = s;
- return this;
- }
-
- @Override
- public Date creationDate() {
- return creationDate;
- }
-
- public DefaultIssue setCreationDate(Date d) {
- // d is not marked as Nullable but we still allow null parameter for unit testing.
- this.creationDate = (d != null ? DateUtils.truncate(d, Calendar.SECOND) : null);
- return this;
- }
-
- @Override
- @CheckForNull
- public Date updateDate() {
- return updateDate;
- }
-
- public DefaultIssue setUpdateDate(@Nullable Date d) {
- this.updateDate = (d != null ? DateUtils.truncate(d, Calendar.SECOND) : null);
- return this;
- }
-
- @Override
- @CheckForNull
- public Date closeDate() {
- return closeDate;
- }
-
- public DefaultIssue setCloseDate(@Nullable Date d) {
- this.closeDate = (d != null ? DateUtils.truncate(d, Calendar.SECOND) : null);
- return this;
- }
-
- @CheckForNull
- public String checksum() {
- return checksum;
- }
-
- public DefaultIssue setChecksum(@Nullable String s) {
- this.checksum = s;
- return this;
- }
-
- @Override
- public boolean isNew() {
- return isNew;
- }
-
- public DefaultIssue setNew(boolean b) {
- isNew = b;
- return this;
- }
-
- /**
- * True when one of the following conditions is true :
- * <ul>
- * <li>the related component has been deleted or renamed</li>
- * <li>the rule has been deleted (eg. on plugin uninstall)</li>
- * <li>the rule has been disabled in the Quality profile</li>
- * </ul>
- */
- public boolean isEndOfLife() {
- return endOfLife;
- }
-
- public DefaultIssue setEndOfLife(boolean b) {
- endOfLife = b;
- return this;
- }
-
- public boolean isOnDisabledRule() {
- return onDisabledRule;
- }
-
- public DefaultIssue setOnDisabledRule(boolean b) {
- onDisabledRule = b;
- return this;
- }
-
- public boolean isChanged() {
- return isChanged;
- }
-
- public DefaultIssue setChanged(boolean b) {
- isChanged = b;
- return this;
- }
-
- public boolean mustSendNotifications() {
- return sendNotifications;
- }
-
- public DefaultIssue setSendNotifications(boolean b) {
- sendNotifications = b;
- return this;
- }
-
- @Override
- @CheckForNull
- public String attribute(String key) {
- return attributes == null ? null : attributes.get(key);
- }
-
- public DefaultIssue setAttribute(String key, @Nullable String value) {
- if (attributes == null) {
- attributes = Maps.newHashMap();
- }
- if (value == null) {
- attributes.remove(key);
- } else {
- attributes.put(key, value);
- }
- return this;
- }
-
- @Override
- public Map<String, String> attributes() {
- return attributes == null ? Collections.<String, String>emptyMap() : ImmutableMap.copyOf(attributes);
- }
-
- public DefaultIssue setAttributes(@Nullable Map<String, String> map) {
- if (map != null) {
- if (attributes == null) {
- attributes = Maps.newHashMap();
- }
- attributes.putAll(map);
- }
- return this;
- }
-
- @Override
- @CheckForNull
- public String authorLogin() {
- return authorLogin;
- }
-
- public DefaultIssue setAuthorLogin(@Nullable String s) {
- this.authorLogin = s;
- return this;
- }
-
- @Override
- @CheckForNull
- public String actionPlanKey() {
- return actionPlanKey;
- }
-
- public DefaultIssue setActionPlanKey(@Nullable String actionPlanKey) {
- this.actionPlanKey = actionPlanKey;
- return this;
- }
-
- public DefaultIssue setFieldChange(IssueChangeContext context, String field, @Nullable Serializable oldValue, @Nullable Serializable newValue) {
- if (!Objects.equal(oldValue, newValue)) {
- if (currentChange == null) {
- currentChange = new FieldDiffs();
- currentChange.setUserLogin(context.login());
- currentChange.setCreationDate(context.date());
- }
- currentChange.setDiff(field, oldValue, newValue);
- }
- addChange(currentChange);
- return this;
- }
-
- public DefaultIssue setCurrentChange(FieldDiffs currentChange) {
- this.currentChange = currentChange;
- addChange(currentChange);
- return this;
- }
-
- @CheckForNull
- public FieldDiffs currentChange() {
- return currentChange;
- }
-
- public DefaultIssue addChange(FieldDiffs change) {
- if (changes == null) {
- changes = new ArrayList<>();
- }
- changes.add(change);
- return this;
- }
-
- public DefaultIssue setChanges(List<FieldDiffs> changes) {
- this.changes = changes;
- return this;
- }
-
- public List<FieldDiffs> changes() {
- if (changes == null) {
- return Collections.emptyList();
- }
- return ImmutableList.copyOf(changes);
- }
-
- public DefaultIssue addComment(DefaultIssueComment comment) {
- if (comments == null) {
- comments = new ArrayList<>();
- }
- comments.add(comment);
- return this;
- }
-
- @Override
- public List<IssueComment> comments() {
- if (comments == null) {
- return Collections.emptyList();
- }
- return ImmutableList.copyOf(comments);
- }
-
- @CheckForNull
- public Long selectedAt() {
- return selectedAt;
- }
-
- public DefaultIssue setSelectedAt(@Nullable Long d) {
- this.selectedAt = d;
- return this;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- DefaultIssue that = (DefaultIssue) o;
- return !(key != null ? !key.equals(that.key) : (that.key != null));
- }
-
- @Override
- public int hashCode() {
- return key != null ? key.hashCode() : 0;
- }
-
- @Override
- public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
- }
-
- @Override
- public Collection<String> tags() {
- if (tags == null) {
- return ImmutableSet.of();
- } else {
- return ImmutableSet.copyOf(tags);
- }
- }
-
- public DefaultIssue setTags(Collection<String> tags) {
- this.tags = new LinkedHashSet<>(tags);
- return this;
- }
-}
+++ /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.
- */
-package org.sonar.api.issue.internal;
-
-import org.sonar.api.issue.IssueComment;
-import org.sonar.api.utils.internal.Uuids;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING.
- *
- * @since 3.6
- */
-public class DefaultIssueComment implements Serializable, IssueComment {
-
- private String issueKey;
- private String userLogin;
- private Date createdAt;
- private Date updatedAt;
- private String key;
- private String markdownText;
- private boolean isNew;
-
- public static DefaultIssueComment create(String issueKey, @Nullable String login, String markdownText) {
- DefaultIssueComment comment = new DefaultIssueComment();
- comment.setIssueKey(issueKey);
- comment.setKey(Uuids.create());
- Date now = new Date();
- comment.setUserLogin(login);
- comment.setMarkdownText(markdownText);
- comment.setCreatedAt(now).setUpdatedAt(now);
- comment.setNew(true);
- return comment;
- }
-
- @Override
- public String markdownText() {
- return markdownText;
- }
-
- public DefaultIssueComment setMarkdownText(String s) {
- this.markdownText = s;
- return this;
- }
-
- @Override
- public String issueKey() {
- return issueKey;
- }
-
- public DefaultIssueComment setIssueKey(String s) {
- this.issueKey = s;
- return this;
- }
-
- @Override
- public String key() {
- return key;
- }
-
- public DefaultIssueComment setKey(String key) {
- this.key = key;
- return this;
- }
-
- /**
- * The user who created the comment. Null if it was automatically generated during project scan.
- */
- @Override
- @CheckForNull
- public String userLogin() {
- return userLogin;
- }
-
- public DefaultIssueComment setUserLogin(@Nullable String userLogin) {
- this.userLogin = userLogin;
- return this;
- }
-
- @Override
- public Date createdAt() {
- return createdAt;
- }
-
- public DefaultIssueComment setCreatedAt(Date createdAt) {
- this.createdAt = createdAt;
- return this;
- }
-
- @Override
- public Date updatedAt() {
- return updatedAt;
- }
-
- public DefaultIssueComment setUpdatedAt(@Nullable Date updatedAt) {
- this.updatedAt = updatedAt;
- return this;
- }
-
- public boolean isNew() {
- return isNew;
- }
-
- public DefaultIssueComment setNew(boolean b) {
- isNew = b;
- return this;
- }
-}
+++ /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.
- */
-package org.sonar.api.issue.internal;
-
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import com.google.common.collect.Maps;
-import java.io.Serializable;
-import java.util.Date;
-import java.util.Map;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-/**
- * PLUGINS MUST NOT USE THIS CLASS, EXCEPT FOR UNIT TESTING.
- *
- * @since 3.6
- */
-public class FieldDiffs implements Serializable {
-
- public static final Splitter FIELDS_SPLITTER = Splitter.on(',').omitEmptyStrings();
-
- private String issueKey;
- private String userLogin;
- private Date creationDate;
-
- private final Map<String, Diff> diffs = Maps.newLinkedHashMap();
-
- public Map<String, Diff> diffs() {
- return diffs;
- }
-
- public Diff get(String field) {
- return diffs.get(field);
- }
-
- @CheckForNull
- public String userLogin() {
- return userLogin;
- }
-
- public FieldDiffs setUserLogin(@Nullable String s) {
- this.userLogin = s;
- return this;
- }
-
- public Date creationDate() {
- return creationDate;
- }
-
- public FieldDiffs setCreationDate(Date creationDate) {
- this.creationDate = creationDate;
- return this;
- }
-
- public String issueKey() {
- return issueKey;
- }
-
- public FieldDiffs setIssueKey(String issueKey) {
- this.issueKey = issueKey;
- return this;
- }
-
- @SuppressWarnings("unchecked")
- public FieldDiffs setDiff(String field, @Nullable Serializable oldValue, @Nullable Serializable newValue) {
- Diff diff = diffs.get(field);
- if (diff == null) {
- diff = new Diff(oldValue, newValue);
- diffs.put(field, diff);
- } else {
- diff.setNewValue(newValue);
- }
- return this;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- boolean notFirst = false;
- for (Map.Entry<String, Diff> entry : diffs.entrySet()) {
- if (notFirst) {
- sb.append(',');
- } else {
- notFirst = true;
- }
- sb.append(entry.getKey());
- sb.append('=');
- sb.append(entry.getValue().toString());
- }
- return sb.toString();
- }
-
- public static FieldDiffs parse(@Nullable String s) {
- FieldDiffs diffs = new FieldDiffs();
- if (!Strings.isNullOrEmpty(s)) {
- Iterable<String> fields = FIELDS_SPLITTER.split(s);
- for (String field : fields) {
- String[] keyValues = field.split("=");
- if (keyValues.length == 2) {
- String[] values = keyValues[1].split("\\|");
- String oldValue = "";
- String newValue = "";
- if(values.length == 1) {
- newValue = Strings.nullToEmpty(values[0]);
- } else if(values.length == 2) {
- oldValue = Strings.nullToEmpty(values[0]);
- newValue = Strings.nullToEmpty(values[1]);
- }
- diffs.setDiff(keyValues[0], oldValue, newValue);
- } else {
- diffs.setDiff(keyValues[0], "", "");
- }
- }
- }
- return diffs;
- }
-
- public static class Diff<T extends Serializable> implements Serializable {
- private T oldValue;
- private T newValue;
-
- public Diff(@Nullable T oldValue, @Nullable T newValue) {
- this.oldValue = oldValue;
- this.newValue = newValue;
- }
-
- @CheckForNull
- public T oldValue() {
- return oldValue;
- }
-
- @CheckForNull
- public Long oldValueLong() {
- return toLong(oldValue);
- }
-
- @CheckForNull
- public T newValue() {
- return newValue;
- }
-
- @CheckForNull
- public Long newValueLong() {
- return toLong(newValue);
- }
-
- void setNewValue(T t) {
- this.newValue = t;
- }
-
- @CheckForNull
- private static Long toLong(@Nullable Serializable value) {
- if (value != null && !"".equals(value)) {
- try {
- return Long.valueOf((String) value);
- } catch (ClassCastException e) {
- return (Long) value;
- }
- }
- return null;
- }
-
- @Override
- public String toString() {
- //TODO escape , and | characters
- StringBuilder sb = new StringBuilder();
- if(newValue != null) {
- if(oldValue != null) {
- sb.append(oldValue.toString());
- sb.append('|');
- }
- sb.append(newValue.toString());
- }
- return sb.toString();
- }
- }
-}
+++ /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.
- */
-package org.sonar.api.issue.internal;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING.
- *
- * @since 3.6
- */
-public class IssueChangeContext implements Serializable {
-
- private final String login;
- private final Date date;
- private final boolean scan;
-
- private IssueChangeContext(@Nullable String login, Date date, boolean scan) {
- this.login = login;
- this.date = date;
- this.scan = scan;
- }
-
- @CheckForNull
- public String login() {
- return login;
- }
-
- public Date date() {
- return date;
- }
-
- public boolean scan() {
- return scan;
- }
-
- public static IssueChangeContext createScan(Date date) {
- return new IssueChangeContext(null, date, true);
- }
-
- public static IssueChangeContext createUser(Date date, @Nullable String login) {
- return new IssueChangeContext(login, date, false);
- }
-}
+++ /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.
- */
-/**
- * This package contains classes that MUST NOT be used by plugins,
- * except for unit testing.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.api.issue.internal;
-
-import javax.annotation.ParametersAreNonnullByDefault;
* 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.issue.action;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.issue.condition.Condition;
-import org.sonar.api.issue.internal.DefaultIssue;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ActionTest {
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- Condition condition1 = mock(Condition.class);
- Condition condition2 = mock(Condition.class);
- Function function1 = mock(Function.class);
- Function function2 = mock(Function.class);
-
- @Test
- public void test_action() throws Exception {
- Action action = new Action("link-to-jira")
- .setConditions(condition1, condition2)
- .setFunctions(function1, function2);
-
- assertThat(action.key()).isEqualTo("link-to-jira");
- assertThat(action.conditions()).containsOnly(condition1, condition2);
- assertThat(action.functions()).containsOnly(function1, function2);
- }
-
- @Test
- public void key_should_be_set() {
- thrown.expectMessage("Action key must be set");
-
- new Action("");
- }
-
- @Test
- public void should_verify_conditions() {
- DefaultIssue issue = new DefaultIssue();
- Action action = new Action("link-to-jira")
- .setConditions(condition1, condition2);
-
- when(condition1.matches(issue)).thenReturn(true);
- when(condition2.matches(issue)).thenReturn(false);
- assertThat(action.supports(issue)).isFalse();
-
- when(condition1.matches(issue)).thenReturn(true);
- when(condition2.matches(issue)).thenReturn(true);
- assertThat(action.supports(issue)).isTrue();
- }
-
- @Test
- public void test_equals_and_hashCode() throws Exception {
- Action t1 = new Action("link-to-jira");
- Action t2 = new Action("link-to-jira");
- Action t3 = new Action("comment");
-
- assertThat(t1).isEqualTo(t1);
- assertThat(t1).isEqualTo(t2);
- assertThat(t1).isNotEqualTo(t3);
-
- assertThat(t1.hashCode()).isEqualTo(t1.hashCode());
- }
-
- @Test
- public void test_toString() throws Exception {
- Action t1 = new Action("link-to-jira");
- assertThat(t1.toString()).isEqualTo("link-to-jira");
- }
-
-}
+///*
+// * 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.
+// */
+//
+//package org.sonar.api.issue.action;
+//
+//import org.junit.Rule;
+//import org.junit.Test;
+//import org.junit.rules.ExpectedException;
+//import org.sonar.api.issue.condition.Condition;
+//import org.sonar.api.issue.internal.DefaultIssue;
+//
+//import static org.assertj.core.api.Assertions.assertThat;
+//import static org.mockito.Mockito.mock;
+//import static org.mockito.Mockito.when;
+//
+//public class ActionTest {
+// @Rule
+// public ExpectedException thrown = ExpectedException.none();
+//
+// Condition condition1 = mock(Condition.class);
+// Condition condition2 = mock(Condition.class);
+// Function function1 = mock(Function.class);
+// Function function2 = mock(Function.class);
+//
+// @Test
+// public void test_action() throws Exception {
+// Action action = new Action("link-to-jira")
+// .setConditions(condition1, condition2)
+// .setFunctions(function1, function2);
+//
+// assertThat(action.key()).isEqualTo("link-to-jira");
+// assertThat(action.conditions()).containsOnly(condition1, condition2);
+// assertThat(action.functions()).containsOnly(function1, function2);
+// }
+//
+// @Test
+// public void key_should_be_set() {
+// thrown.expectMessage("Action key must be set");
+//
+// new Action("");
+// }
+//
+// @Test
+// public void should_verify_conditions() {
+// DefaultIssue issue = new DefaultIssue();
+// Action action = new Action("link-to-jira")
+// .setConditions(condition1, condition2);
+//
+// when(condition1.matches(issue)).thenReturn(true);
+// when(condition2.matches(issue)).thenReturn(false);
+// assertThat(action.supports(issue)).isFalse();
+//
+// when(condition1.matches(issue)).thenReturn(true);
+// when(condition2.matches(issue)).thenReturn(true);
+// assertThat(action.supports(issue)).isTrue();
+// }
+//
+// @Test
+// public void test_equals_and_hashCode() throws Exception {
+// Action t1 = new Action("link-to-jira");
+// Action t2 = new Action("link-to-jira");
+// Action t3 = new Action("comment");
+//
+// assertThat(t1).isEqualTo(t1);
+// assertThat(t1).isEqualTo(t2);
+// assertThat(t1).isNotEqualTo(t3);
+//
+// assertThat(t1.hashCode()).isEqualTo(t1.hashCode());
+// }
+//
+// @Test
+// public void test_toString() throws Exception {
+// Action t1 = new Action("link-to-jira");
+// assertThat(t1.toString()).isEqualTo("link-to-jira");
+// }
+//
+//}
* 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.issue.condition;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.issue.internal.DefaultIssue;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class HasIssuePropertyConditionTest {
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- DefaultIssue issue = new DefaultIssue();
-
- @Test
- public void should_match() {
- HasIssuePropertyCondition condition = new HasIssuePropertyCondition("foo");
-
- assertThat(condition.matches(issue)).isFalse();
- assertThat(condition.matches(issue.setAttribute("foo", ""))).isFalse();
- assertThat(condition.matches(issue.setAttribute("foo", "bar"))).isTrue();
- }
-
- @Test
- public void should_get_property_key() {
- HasIssuePropertyCondition condition = new HasIssuePropertyCondition("foo");
- assertThat(condition.getPropertyKey()).isEqualTo("foo");
- }
-
- @Test
- public void shoul_fail_if_null_property() {
- thrown.expect(IllegalArgumentException.class);
- new HasIssuePropertyCondition(null);
- }
-
- @Test
- public void should_fail_if_empty_property() {
- thrown.expect(IllegalArgumentException.class);
- new HasIssuePropertyCondition("");
- }
-
-}
+///*
+// * 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.
+// */
+//package org.sonar.api.issue.condition;
+//
+//import org.junit.Rule;
+//import org.junit.Test;
+//import org.junit.rules.ExpectedException;
+//import org.sonar.api.issue.internal.DefaultIssue;
+//
+//import static org.assertj.core.api.Assertions.assertThat;
+//
+//public class HasIssuePropertyConditionTest {
+//
+// @Rule
+// public ExpectedException thrown = ExpectedException.none();
+//
+// DefaultIssue issue = new DefaultIssue();
+//
+// @Test
+// public void should_match() {
+// HasIssuePropertyCondition condition = new HasIssuePropertyCondition("foo");
+//
+// assertThat(condition.matches(issue)).isFalse();
+// assertThat(condition.matches(issue.setAttribute("foo", ""))).isFalse();
+// assertThat(condition.matches(issue.setAttribute("foo", "bar"))).isTrue();
+// }
+//
+// @Test
+// public void should_get_property_key() {
+// HasIssuePropertyCondition condition = new HasIssuePropertyCondition("foo");
+// assertThat(condition.getPropertyKey()).isEqualTo("foo");
+// }
+//
+// @Test
+// public void shoul_fail_if_null_property() {
+// thrown.expect(IllegalArgumentException.class);
+// new HasIssuePropertyCondition(null);
+// }
+//
+// @Test
+// public void should_fail_if_empty_property() {
+// thrown.expect(IllegalArgumentException.class);
+// new HasIssuePropertyCondition("");
+// }
+//
+//}
* 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.issue.condition;
-
-import org.junit.Test;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class HasResolutionTest {
-
- DefaultIssue issue = new DefaultIssue();
-
- @Test
- public void should_match() {
- HasResolution condition = new HasResolution(Issue.RESOLUTION_FIXED, Issue.RESOLUTION_FALSE_POSITIVE);
-
- assertThat(condition.matches(issue.setResolution("FIXED"))).isTrue();
- assertThat(condition.matches(issue.setResolution("FALSE-POSITIVE"))).isTrue();
-
- assertThat(condition.matches(issue.setResolution("Fixed"))).isFalse();
- }
-}
+///*
+// * 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.
+// */
+//package org.sonar.api.issue.condition;
+//
+//import org.junit.Test;
+//import org.sonar.api.issue.Issue;
+//import org.sonar.api.issue.internal.DefaultIssue;
+//
+//import static org.assertj.core.api.Assertions.assertThat;
+//
+//public class HasResolutionTest {
+//
+// DefaultIssue issue = new DefaultIssue();
+//
+// @Test
+// public void should_match() {
+// HasResolution condition = new HasResolution(Issue.RESOLUTION_FIXED, Issue.RESOLUTION_FALSE_POSITIVE);
+//
+// assertThat(condition.matches(issue.setResolution("FIXED"))).isTrue();
+// assertThat(condition.matches(issue.setResolution("FALSE-POSITIVE"))).isTrue();
+//
+// assertThat(condition.matches(issue.setResolution("Fixed"))).isFalse();
+// }
+//}
* 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.issue.condition;
-
-import org.junit.Test;
-import org.sonar.api.issue.internal.DefaultIssue;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class HasStatusTest {
-
- DefaultIssue issue = new DefaultIssue();
-
- @Test
- public void should_match() {
- HasStatus condition = new HasStatus("OPEN", "REOPENED", "CONFIRMED");
-
- assertThat(condition.matches(issue.setStatus("OPEN"))).isTrue();
- assertThat(condition.matches(issue.setStatus("REOPENED"))).isTrue();
- assertThat(condition.matches(issue.setStatus("CONFIRMED"))).isTrue();
-
- assertThat(condition.matches(issue.setStatus("open"))).isFalse();
- assertThat(condition.matches(issue.setStatus("CLOSED"))).isFalse();
- }
-
-}
+///*
+// * 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.
+// */
+//
+//package org.sonar.api.issue.condition;
+//
+//import org.junit.Test;
+//import org.sonar.api.issue.internal.DefaultIssue;
+//
+//import static org.assertj.core.api.Assertions.assertThat;
+//
+//public class HasStatusTest {
+//
+// DefaultIssue issue = new DefaultIssue();
+//
+// @Test
+// public void should_match() {
+// HasStatus condition = new HasStatus("OPEN", "REOPENED", "CONFIRMED");
+//
+// assertThat(condition.matches(issue.setStatus("OPEN"))).isTrue();
+// assertThat(condition.matches(issue.setStatus("REOPENED"))).isTrue();
+// assertThat(condition.matches(issue.setStatus("CONFIRMED"))).isTrue();
+//
+// assertThat(condition.matches(issue.setStatus("open"))).isFalse();
+// assertThat(condition.matches(issue.setStatus("CLOSED"))).isFalse();
+// }
+//
+//}
* 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.issue.condition;
-
-import org.junit.Test;
-import org.sonar.api.issue.internal.DefaultIssue;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class IsUnResolvedTest {
-
- DefaultIssue issue = new DefaultIssue();
-
- @Test
- public void should_match() {
- IsUnResolved condition = new IsUnResolved();
-
- assertThat(condition.matches(issue)).isTrue();
- assertThat(condition.matches(issue.setResolution("FIXED"))).isFalse();
- }
-}
+///*
+// * 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.
+// */
+//
+//package org.sonar.api.issue.condition;
+//
+//import org.junit.Test;
+//import org.sonar.api.issue.internal.DefaultIssue;
+//
+//import static org.assertj.core.api.Assertions.assertThat;
+//
+//public class IsUnResolvedTest {
+//
+// DefaultIssue issue = new DefaultIssue();
+//
+// @Test
+// public void should_match() {
+// IsUnResolved condition = new IsUnResolved();
+//
+// assertThat(condition.matches(issue)).isTrue();
+// assertThat(condition.matches(issue.setResolution("FIXED"))).isFalse();
+// }
+//}
* 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.issue.condition;
-
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.when;
-
-public class NotConditionTest {
-
- Condition target = Mockito.mock(Condition.class);
-
- @Test
- public void should_match_opposite() {
- NotCondition condition = new NotCondition(target);
-
- when(target.matches(any(Issue.class))).thenReturn(true);
- assertThat(condition.matches(new DefaultIssue())).isFalse();
-
- when(target.matches(any(Issue.class))).thenReturn(false);
- assertThat(condition.matches(new DefaultIssue())).isTrue();
- }
-}
+///*
+// * 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.
+// */
+//package org.sonar.api.issue.condition;
+//
+//import org.junit.Test;
+//import org.mockito.Mockito;
+//import org.sonar.api.issue.Issue;
+//import org.sonar.api.issue.internal.DefaultIssue;
+//
+//import static org.assertj.core.api.Assertions.assertThat;
+//import static org.mockito.Matchers.any;
+//import static org.mockito.Mockito.when;
+//
+//public class NotConditionTest {
+//
+// Condition target = Mockito.mock(Condition.class);
+//
+// @Test
+// public void should_match_opposite() {
+// NotCondition condition = new NotCondition(target);
+//
+// when(target.matches(any(Issue.class))).thenReturn(true);
+// assertThat(condition.matches(new DefaultIssue())).isFalse();
+//
+// when(target.matches(any(Issue.class))).thenReturn(false);
+// assertThat(condition.matches(new DefaultIssue())).isTrue();
+// }
+//}
* 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.issue.internal;
-
-import com.google.common.collect.ImmutableMap;
-import org.apache.commons.lang.StringUtils;
-import org.junit.Test;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueComment;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.utils.Duration;
-
-import java.text.SimpleDateFormat;
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.entry;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-
-public class DefaultIssueTest {
-
- DefaultIssue issue = new DefaultIssue();
-
- @Test
- public void test_setters_and_getters() throws Exception {
- issue.setKey("ABCD")
- .setComponentKey("org.sample.Sample")
- .setProjectKey("Sample")
- .setRuleKey(RuleKey.of("squid", "S100"))
- .setLanguage("xoo")
- .setSeverity("MINOR")
- .setManualSeverity(true)
- .setMessage("a message")
- .setLine(7)
- .setEffortToFix(1.2d)
- .setDebt(Duration.create(28800L))
- .setActionPlanKey("BCDE")
- .setStatus(Issue.STATUS_CLOSED)
- .setResolution(Issue.RESOLUTION_FIXED)
- .setReporter("simon")
- .setAssignee("julien")
- .setAuthorLogin("steph")
- .setChecksum("c7b5db46591806455cf082bb348631e8")
- .setNew(true)
- .setEndOfLife(true)
- .setOnDisabledRule(true)
- .setChanged(true)
- .setSendNotifications(true)
- .setCreationDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-19"))
- .setUpdateDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-20"))
- .setCloseDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-21"))
- .setSelectedAt(1400000000000L);
-
- assertThat(issue.key()).isEqualTo("ABCD");
- assertThat(issue.componentKey()).isEqualTo("org.sample.Sample");
- assertThat(issue.projectKey()).isEqualTo("Sample");
- assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("squid", "S100"));
- assertThat(issue.language()).isEqualTo("xoo");
- assertThat(issue.severity()).isEqualTo("MINOR");
- assertThat(issue.manualSeverity()).isTrue();
- assertThat(issue.message()).isEqualTo("a message");
- assertThat(issue.line()).isEqualTo(7);
- assertThat(issue.effortToFix()).isEqualTo(1.2d);
- assertThat(issue.debt()).isEqualTo(Duration.create(28800L));
- assertThat(issue.actionPlanKey()).isEqualTo("BCDE");
- assertThat(issue.status()).isEqualTo(Issue.STATUS_CLOSED);
- assertThat(issue.resolution()).isEqualTo(Issue.RESOLUTION_FIXED);
- assertThat(issue.reporter()).isEqualTo("simon");
- assertThat(issue.assignee()).isEqualTo("julien");
- assertThat(issue.authorLogin()).isEqualTo("steph");
- assertThat(issue.checksum()).isEqualTo("c7b5db46591806455cf082bb348631e8");
- assertThat(issue.isNew()).isTrue();
- assertThat(issue.isEndOfLife()).isTrue();
- assertThat(issue.isOnDisabledRule()).isTrue();
- assertThat(issue.isChanged()).isTrue();
- assertThat(issue.mustSendNotifications()).isTrue();
- assertThat(issue.creationDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-19"));
- assertThat(issue.updateDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-20"));
- assertThat(issue.closeDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-21"));
- assertThat(issue.selectedAt()).isEqualTo(1400000000000L);
- }
-
- @Test
- public void set_empty_dates() {
- issue
- .setCreationDate(null)
- .setUpdateDate(null)
- .setCloseDate(null)
- .setSelectedAt(null);
-
- assertThat(issue.creationDate()).isNull();
- assertThat(issue.updateDate()).isNull();
- assertThat(issue.closeDate()).isNull();
- assertThat(issue.selectedAt()).isNull();
- }
-
- @Test
- public void test_attributes() throws Exception {
- assertThat(issue.attribute("foo")).isNull();
- issue.setAttribute("foo", "bar");
- assertThat(issue.attribute("foo")).isEqualTo("bar");
- issue.setAttribute("foo", "newbar");
- assertThat(issue.attribute("foo")).isEqualTo("newbar");
- issue.setAttribute("foo", null);
- assertThat(issue.attribute("foo")).isNull();
- }
-
- @Test
- public void setAttributes_should_not_clear_existing_values() {
- issue.setAttributes(ImmutableMap.of("1", "one"));
- assertThat(issue.attribute("1")).isEqualTo("one");
-
- issue.setAttributes(ImmutableMap.of("2", "two"));
- assertThat(issue.attributes()).containsOnly(entry("1", "one"), entry("2", "two"));
-
- issue.setAttributes(null);
- assertThat(issue.attributes()).containsOnly(entry("1", "one"), entry("2", "two"));
- }
-
- @Test
- public void fail_on_empty_status() {
- try {
- issue.setStatus("");
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e).hasMessage("Status must be set");
- }
- }
-
- @Test
- public void fail_on_bad_severity() {
- try {
- issue.setSeverity("FOO");
- fail();
- } catch (IllegalArgumentException e) {
- assertThat(e).hasMessage("Not a valid severity: FOO");
- }
- }
-
- @Test
- public void message_should_be_abbreviated_if_too_long() {
- issue.setMessage(StringUtils.repeat("a", 5000));
- assertThat(issue.message()).hasSize(4000);
- }
-
- @Test
- public void message_should_be_trimmed() {
- issue.setMessage(" foo ");
- assertThat(issue.message()).isEqualTo("foo");
- }
-
- @Test
- public void message_could_be_null() {
- issue.setMessage(null);
- assertThat(issue.message()).isNull();
- }
-
- @Test
- public void test_nullable_fields() throws Exception {
- issue.setEffortToFix(null).setSeverity(null).setLine(null);
- assertThat(issue.effortToFix()).isNull();
- assertThat(issue.severity()).isNull();
- assertThat(issue.line()).isNull();
- }
-
- @Test
- public void test_equals_and_hashCode() throws Exception {
- DefaultIssue a1 = new DefaultIssue().setKey("AAA");
- DefaultIssue a2 = new DefaultIssue().setKey("AAA");
- DefaultIssue b = new DefaultIssue().setKey("BBB");
- assertThat(a1).isEqualTo(a1);
- assertThat(a1).isEqualTo(a2);
- assertThat(a1).isNotEqualTo(b);
- assertThat(a1.hashCode()).isEqualTo(a1.hashCode());
- }
-
- @Test
- public void comments_should_not_be_modifiable() {
- DefaultIssue issue = new DefaultIssue().setKey("AAA");
-
- List<IssueComment> comments = issue.comments();
- assertThat(comments).isEmpty();
-
- try {
- comments.add(new DefaultIssueComment());
- fail();
- } catch (UnsupportedOperationException e) {
- // ok
- } catch (Exception e) {
- fail("Unexpected exception: " + e);
- }
- }
-
- @Test
- public void all_changes_contain_current_change() {
- IssueChangeContext issueChangeContext = mock(IssueChangeContext.class);
- DefaultIssue issue = new DefaultIssue().setKey("AAA").setFieldChange(issueChangeContext, "actionPlan", "1.0", "1.1");
-
- assertThat(issue.changes()).hasSize(1);
- }
-}
+///*
+// * 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.
+// */
+//package org.sonar.api.issue.internal;
+//
+//import com.google.common.collect.ImmutableMap;
+//import org.apache.commons.lang.StringUtils;
+//import org.junit.Test;
+//import org.sonar.api.issue.Issue;
+//import org.sonar.api.issue.IssueComment;
+//import org.sonar.api.rule.RuleKey;
+//import org.sonar.api.utils.Duration;
+//
+//import java.text.SimpleDateFormat;
+//import java.util.List;
+//
+//import static org.assertj.core.api.Assertions.assertThat;
+//import static org.assertj.core.api.Assertions.entry;
+//import static org.junit.Assert.fail;
+//import static org.mockito.Mockito.mock;
+//
+//public class DefaultIssueTest {
+//
+// DefaultIssue issue = new DefaultIssue();
+//
+// @Test
+// public void test_setters_and_getters() throws Exception {
+// issue.setKey("ABCD")
+// .setComponentKey("org.sample.Sample")
+// .setProjectKey("Sample")
+// .setRuleKey(RuleKey.of("squid", "S100"))
+// .setLanguage("xoo")
+// .setSeverity("MINOR")
+// .setManualSeverity(true)
+// .setMessage("a message")
+// .setLine(7)
+// .setEffortToFix(1.2d)
+// .setDebt(Duration.create(28800L))
+// .setActionPlanKey("BCDE")
+// .setStatus(Issue.STATUS_CLOSED)
+// .setResolution(Issue.RESOLUTION_FIXED)
+// .setReporter("simon")
+// .setAssignee("julien")
+// .setAuthorLogin("steph")
+// .setChecksum("c7b5db46591806455cf082bb348631e8")
+// .setNew(true)
+// .setBeingClosed(true)
+// .setOnDisabledRule(true)
+// .setChanged(true)
+// .setSendNotifications(true)
+// .setCreationDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-19"))
+// .setUpdateDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-20"))
+// .setCloseDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-21"))
+// .setSelectedAt(1400000000000L);
+//
+// assertThat(issue.key()).isEqualTo("ABCD");
+// assertThat(issue.componentKey()).isEqualTo("org.sample.Sample");
+// assertThat(issue.projectKey()).isEqualTo("Sample");
+// assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("squid", "S100"));
+// assertThat(issue.language()).isEqualTo("xoo");
+// assertThat(issue.severity()).isEqualTo("MINOR");
+// assertThat(issue.manualSeverity()).isTrue();
+// assertThat(issue.message()).isEqualTo("a message");
+// assertThat(issue.line()).isEqualTo(7);
+// assertThat(issue.effortToFix()).isEqualTo(1.2d);
+// assertThat(issue.debt()).isEqualTo(Duration.create(28800L));
+// assertThat(issue.actionPlanKey()).isEqualTo("BCDE");
+// assertThat(issue.status()).isEqualTo(Issue.STATUS_CLOSED);
+// assertThat(issue.resolution()).isEqualTo(Issue.RESOLUTION_FIXED);
+// assertThat(issue.reporter()).isEqualTo("simon");
+// assertThat(issue.assignee()).isEqualTo("julien");
+// assertThat(issue.authorLogin()).isEqualTo("steph");
+// assertThat(issue.checksum()).isEqualTo("c7b5db46591806455cf082bb348631e8");
+// assertThat(issue.isNew()).isTrue();
+// assertThat(issue.isBeingClosed()).isTrue();
+// assertThat(issue.isOnDisabledRule()).isTrue();
+// assertThat(issue.isChanged()).isTrue();
+// assertThat(issue.mustSendNotifications()).isTrue();
+// assertThat(issue.creationDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-19"));
+// assertThat(issue.updateDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-20"));
+// assertThat(issue.closeDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-21"));
+// assertThat(issue.selectedAt()).isEqualTo(1400000000000L);
+// }
+//
+// @Test
+// public void set_empty_dates() {
+// issue
+// .setCreationDate(null)
+// .setUpdateDate(null)
+// .setCloseDate(null)
+// .setSelectedAt(null);
+//
+// assertThat(issue.creationDate()).isNull();
+// assertThat(issue.updateDate()).isNull();
+// assertThat(issue.closeDate()).isNull();
+// assertThat(issue.selectedAt()).isNull();
+// }
+//
+// @Test
+// public void test_attributes() throws Exception {
+// assertThat(issue.attribute("foo")).isNull();
+// issue.setAttribute("foo", "bar");
+// assertThat(issue.attribute("foo")).isEqualTo("bar");
+// issue.setAttribute("foo", "newbar");
+// assertThat(issue.attribute("foo")).isEqualTo("newbar");
+// issue.setAttribute("foo", null);
+// assertThat(issue.attribute("foo")).isNull();
+// }
+//
+// @Test
+// public void setAttributes_should_not_clear_existing_values() {
+// issue.setAttributes(ImmutableMap.of("1", "one"));
+// assertThat(issue.attribute("1")).isEqualTo("one");
+//
+// issue.setAttributes(ImmutableMap.of("2", "two"));
+// assertThat(issue.attributes()).containsOnly(entry("1", "one"), entry("2", "two"));
+//
+// issue.setAttributes(null);
+// assertThat(issue.attributes()).containsOnly(entry("1", "one"), entry("2", "two"));
+// }
+//
+// @Test
+// public void fail_on_empty_status() {
+// try {
+// issue.setStatus("");
+// fail();
+// } catch (IllegalArgumentException e) {
+// assertThat(e).hasMessage("Status must be set");
+// }
+// }
+//
+// @Test
+// public void fail_on_bad_severity() {
+// try {
+// issue.setSeverity("FOO");
+// fail();
+// } catch (IllegalArgumentException e) {
+// assertThat(e).hasMessage("Not a valid severity: FOO");
+// }
+// }
+//
+// @Test
+// public void message_should_be_abbreviated_if_too_long() {
+// issue.setMessage(StringUtils.repeat("a", 5000));
+// assertThat(issue.message()).hasSize(4000);
+// }
+//
+// @Test
+// public void message_should_be_trimmed() {
+// issue.setMessage(" foo ");
+// assertThat(issue.message()).isEqualTo("foo");
+// }
+//
+// @Test
+// public void message_could_be_null() {
+// issue.setMessage(null);
+// assertThat(issue.message()).isNull();
+// }
+//
+// @Test
+// public void test_nullable_fields() throws Exception {
+// issue.setEffortToFix(null).setSeverity(null).setLine(null);
+// assertThat(issue.effortToFix()).isNull();
+// assertThat(issue.severity()).isNull();
+// assertThat(issue.line()).isNull();
+// }
+//
+// @Test
+// public void test_equals_and_hashCode() throws Exception {
+// DefaultIssue a1 = new DefaultIssue().setKey("AAA");
+// DefaultIssue a2 = new DefaultIssue().setKey("AAA");
+// DefaultIssue b = new DefaultIssue().setKey("BBB");
+// assertThat(a1).isEqualTo(a1);
+// assertThat(a1).isEqualTo(a2);
+// assertThat(a1).isNotEqualTo(b);
+// assertThat(a1.hashCode()).isEqualTo(a1.hashCode());
+// }
+//
+// @Test
+// public void comments_should_not_be_modifiable() {
+// DefaultIssue issue = new DefaultIssue().setKey("AAA");
+//
+// List<IssueComment> comments = issue.comments();
+// assertThat(comments).isEmpty();
+//
+// try {
+// comments.add(new DefaultIssueComment());
+// fail();
+// } catch (UnsupportedOperationException e) {
+// // ok
+// } catch (Exception e) {
+// fail("Unexpected exception: " + e);
+// }
+// }
+//
+// @Test
+// public void all_changes_contain_current_change() {
+// IssueChangeContext issueChangeContext = mock(IssueChangeContext.class);
+// DefaultIssue issue = new DefaultIssue().setKey("AAA").setFieldChange(issueChangeContext, "actionPlan", "1.0", "1.1");
+//
+// assertThat(issue.changes()).hasSize(1);
+// }
+//}
* 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.issue.internal;
-
-import org.junit.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class FieldDiffsTest {
-
- FieldDiffs diffs = new FieldDiffs();
-
- @Test
- public void diffs_should_be_empty_by_default() {
- assertThat(diffs.diffs()).isEmpty();
- }
-
- @Test
- public void test_diff() throws Exception {
- diffs.setDiff("severity", "BLOCKER", "INFO");
- diffs.setDiff("resolution", "OPEN", "FIXED");
-
- assertThat(diffs.diffs()).hasSize(2);
-
- FieldDiffs.Diff diff = diffs.diffs().get("severity");
- assertThat(diff.oldValue()).isEqualTo("BLOCKER");
- assertThat(diff.newValue()).isEqualTo("INFO");
-
- diff = diffs.diffs().get("resolution");
- assertThat(diff.oldValue()).isEqualTo("OPEN");
- assertThat(diff.newValue()).isEqualTo("FIXED");
- }
-
- @Test
- public void diff_with_long_values() {
- diffs.setDiff("technicalDebt", 50l, "100");
-
- FieldDiffs.Diff diff = diffs.diffs().get("technicalDebt");
- assertThat(diff.oldValueLong()).isEqualTo(50l);
- assertThat(diff.newValueLong()).isEqualTo(100l);
- }
-
- @Test
- public void diff_with_empty_long_values() {
- diffs.setDiff("technicalDebt", null, "");
-
- FieldDiffs.Diff diff = diffs.diffs().get("technicalDebt");
- assertThat(diff.oldValueLong()).isNull();
- assertThat(diff.newValueLong()).isNull();
- }
-
- @Test
- public void test_diff_by_key() throws Exception {
- diffs.setDiff("severity", "BLOCKER", "INFO");
- diffs.setDiff("resolution", "OPEN", "FIXED");
-
- assertThat(diffs.diffs()).hasSize(2);
-
- FieldDiffs.Diff diff = diffs.diffs().get("severity");
- assertThat(diff.oldValue()).isEqualTo("BLOCKER");
- assertThat(diff.newValue()).isEqualTo("INFO");
-
- diff = diffs.diffs().get("resolution");
- assertThat(diff.oldValue()).isEqualTo("OPEN");
- assertThat(diff.newValue()).isEqualTo("FIXED");
- }
-
- @Test
- public void should_keep_old_value() {
- diffs.setDiff("severity", "BLOCKER", "INFO");
- diffs.setDiff("severity", null, "MAJOR");
- FieldDiffs.Diff diff = diffs.diffs().get("severity");
- assertThat(diff.oldValue()).isEqualTo("BLOCKER");
- assertThat(diff.newValue()).isEqualTo("MAJOR");
- }
-
- @Test
- public void test_toString() throws Exception {
- diffs.setDiff("severity", "BLOCKER", "INFO");
- diffs.setDiff("resolution", "OPEN", "FIXED");
-
- assertThat(diffs.toString()).isEqualTo("severity=BLOCKER|INFO,resolution=OPEN|FIXED");
- }
-
- @Test
- public void test_toString_with_null_values() throws Exception {
- diffs.setDiff("severity", null, "INFO");
- diffs.setDiff("assignee", "user1", null);
-
- assertThat(diffs.toString()).isEqualTo("severity=INFO,assignee=");
- }
-
- @Test
- public void test_parse() throws Exception {
- diffs = FieldDiffs.parse("severity=BLOCKER|INFO,resolution=OPEN|FIXED");
- assertThat(diffs.diffs()).hasSize(2);
-
- FieldDiffs.Diff diff = diffs.diffs().get("severity");
- assertThat(diff.oldValue()).isEqualTo("BLOCKER");
- assertThat(diff.newValue()).isEqualTo("INFO");
-
- diff = diffs.diffs().get("resolution");
- assertThat(diff.oldValue()).isEqualTo("OPEN");
- assertThat(diff.newValue()).isEqualTo("FIXED");
- }
-
- @Test
- public void test_parse_empty_values() throws Exception {
- diffs = FieldDiffs.parse("severity=INFO,resolution=");
- assertThat(diffs.diffs()).hasSize(2);
-
- FieldDiffs.Diff diff = diffs.diffs().get("severity");
- assertThat(diff.oldValue()).isEqualTo("");
- assertThat(diff.newValue()).isEqualTo("INFO");
-
- diff = diffs.diffs().get("resolution");
- assertThat(diff.oldValue()).isEqualTo("");
- assertThat(diff.newValue()).isEqualTo("");
- }
-
- @Test
- public void test_parse_null() throws Exception {
- diffs = FieldDiffs.parse(null);
- assertThat(diffs.diffs()).isEmpty();
- }
-
- @Test
- public void test_parse_empty() throws Exception {
- diffs = FieldDiffs.parse("");
- assertThat(diffs.diffs()).isEmpty();
- }
-}
+///*
+// * 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.
+// */
+//package org.sonar.api.issue.internal;
+//
+//import org.junit.Test;
+//
+//import static org.assertj.core.api.Assertions.assertThat;
+//
+//public class FieldDiffsTest {
+//
+// FieldDiffs diffs = new FieldDiffs();
+//
+// @Test
+// public void diffs_should_be_empty_by_default() {
+// assertThat(diffs.diffs()).isEmpty();
+// }
+//
+// @Test
+// public void test_diff() throws Exception {
+// diffs.setDiff("severity", "BLOCKER", "INFO");
+// diffs.setDiff("resolution", "OPEN", "FIXED");
+//
+// assertThat(diffs.diffs()).hasSize(2);
+//
+// FieldDiffs.Diff diff = diffs.diffs().get("severity");
+// assertThat(diff.oldValue()).isEqualTo("BLOCKER");
+// assertThat(diff.newValue()).isEqualTo("INFO");
+//
+// diff = diffs.diffs().get("resolution");
+// assertThat(diff.oldValue()).isEqualTo("OPEN");
+// assertThat(diff.newValue()).isEqualTo("FIXED");
+// }
+//
+// @Test
+// public void diff_with_long_values() {
+// diffs.setDiff("technicalDebt", 50l, "100");
+//
+// FieldDiffs.Diff diff = diffs.diffs().get("technicalDebt");
+// assertThat(diff.oldValueLong()).isEqualTo(50l);
+// assertThat(diff.newValueLong()).isEqualTo(100l);
+// }
+//
+// @Test
+// public void diff_with_empty_long_values() {
+// diffs.setDiff("technicalDebt", null, "");
+//
+// FieldDiffs.Diff diff = diffs.diffs().get("technicalDebt");
+// assertThat(diff.oldValueLong()).isNull();
+// assertThat(diff.newValueLong()).isNull();
+// }
+//
+// @Test
+// public void test_diff_by_key() throws Exception {
+// diffs.setDiff("severity", "BLOCKER", "INFO");
+// diffs.setDiff("resolution", "OPEN", "FIXED");
+//
+// assertThat(diffs.diffs()).hasSize(2);
+//
+// FieldDiffs.Diff diff = diffs.diffs().get("severity");
+// assertThat(diff.oldValue()).isEqualTo("BLOCKER");
+// assertThat(diff.newValue()).isEqualTo("INFO");
+//
+// diff = diffs.diffs().get("resolution");
+// assertThat(diff.oldValue()).isEqualTo("OPEN");
+// assertThat(diff.newValue()).isEqualTo("FIXED");
+// }
+//
+// @Test
+// public void should_keep_old_value() {
+// diffs.setDiff("severity", "BLOCKER", "INFO");
+// diffs.setDiff("severity", null, "MAJOR");
+// FieldDiffs.Diff diff = diffs.diffs().get("severity");
+// assertThat(diff.oldValue()).isEqualTo("BLOCKER");
+// assertThat(diff.newValue()).isEqualTo("MAJOR");
+// }
+//
+// @Test
+// public void test_toString() throws Exception {
+// diffs.setDiff("severity", "BLOCKER", "INFO");
+// diffs.setDiff("resolution", "OPEN", "FIXED");
+//
+// assertThat(diffs.toString()).isEqualTo("severity=BLOCKER|INFO,resolution=OPEN|FIXED");
+// }
+//
+// @Test
+// public void test_toString_with_null_values() throws Exception {
+// diffs.setDiff("severity", null, "INFO");
+// diffs.setDiff("assignee", "user1", null);
+//
+// assertThat(diffs.toString()).isEqualTo("severity=INFO,assignee=");
+// }
+//
+// @Test
+// public void test_parse() throws Exception {
+// diffs = FieldDiffs.parse("severity=BLOCKER|INFO,resolution=OPEN|FIXED");
+// assertThat(diffs.diffs()).hasSize(2);
+//
+// FieldDiffs.Diff diff = diffs.diffs().get("severity");
+// assertThat(diff.oldValue()).isEqualTo("BLOCKER");
+// assertThat(diff.newValue()).isEqualTo("INFO");
+//
+// diff = diffs.diffs().get("resolution");
+// assertThat(diff.oldValue()).isEqualTo("OPEN");
+// assertThat(diff.newValue()).isEqualTo("FIXED");
+// }
+//
+// @Test
+// public void test_parse_empty_values() throws Exception {
+// diffs = FieldDiffs.parse("severity=INFO,resolution=");
+// assertThat(diffs.diffs()).hasSize(2);
+//
+// FieldDiffs.Diff diff = diffs.diffs().get("severity");
+// assertThat(diff.oldValue()).isEqualTo("");
+// assertThat(diff.newValue()).isEqualTo("INFO");
+//
+// diff = diffs.diffs().get("resolution");
+// assertThat(diff.oldValue()).isEqualTo("");
+// assertThat(diff.newValue()).isEqualTo("");
+// }
+//
+// @Test
+// public void test_parse_null() throws Exception {
+// diffs = FieldDiffs.parse(null);
+// assertThat(diffs.diffs()).isEmpty();
+// }
+//
+// @Test
+// public void test_parse_empty() throws Exception {
+// diffs = FieldDiffs.parse("");
+// assertThat(diffs.diffs()).isEmpty();
+// }
+//}