Merge "Differentiate RobotComment and HumanComment"

This commit is contained in:
Gal Paikin
2020-06-24 11:44:08 +00:00
committed by Gerrit Code Review
63 changed files with 608 additions and 453 deletions

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.common.data;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import java.util.ArrayList;
import java.util.List;
@@ -36,7 +37,7 @@ public class CommentDetail {
protected CommentDetail() {}
public void include(Change.Id changeId, Comment p) {
public void include(Change.Id changeId, HumanComment p) {
PatchSet.Id psId = PatchSet.id(changeId, p.key.patchSetId);
if (p.side == 0) {
if (idA == null && idB.equals(psId)) {

View File

@@ -39,7 +39,7 @@ import java.util.Optional;
* |
* +- {@link PatchSetApproval}: a +/- vote on the change's current state.
* |
* +- {@link Comment}: comment about a specific line
* +- {@link HumanComment}: comment about a specific line
* </pre>
*
* <p>

View File

@@ -24,15 +24,15 @@ import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
/**
* This class represents inline comments in NoteDb. This means it determines the JSON format for
* inline comments in the revision notes that NoteDb uses to persist inline comments.
* This class is a base class that can be extended by the different types of inline comment
* entities.
*
* <p>Changing fields in this class changes the storage format of inline comments in NoteDb and may
* require a corresponding data migration (adding new optional fields is generally okay).
*
* <p>Consider updating {@link #getApproximateSize()} when adding/changing fields.
* <p>Consider updating {@link #getCommentFieldApproximateSize()} when adding/changing fields.
*/
public class Comment {
public abstract class Comment {
public enum Status {
DRAFT('d'),
@@ -301,11 +301,13 @@ public class Comment {
* Returns the comment's approximate size. This is used to enforce size limits and should
* therefore include all unbounded fields (e.g. String-s).
*/
public int getApproximateSize() {
protected int getCommentFieldApproximateSize() {
return nullableLength(message, parentUuid, tag, revId, serverId)
+ (key != null ? nullableLength(key.filename, key.uuid) : 0);
}
public abstract int getApproximateSize();
static int nullableLength(String... strings) {
int length = 0;
for (String s : strings) {

View File

@@ -0,0 +1,67 @@
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.entities;
import java.sql.Timestamp;
/**
* This class represents inline human comments in NoteDb. This means it determines the JSON format
* for inline comments in the revision notes that NoteDb uses to persist inline comments.
*
* <p>Changing fields in this class changes the storage format of inline comments in NoteDb and may
* require a corresponding data migration (adding new optional fields is generally okay).
*
* <p>Consider updating {@link #getApproximateSize()} when adding/changing fields.
*/
public class HumanComment extends Comment {
public HumanComment(
Key key,
Account.Id author,
Timestamp writtenOn,
short side,
String message,
String serverId,
boolean unresolved) {
super(key, author, writtenOn, side, message, serverId, unresolved);
}
public HumanComment(HumanComment comment) {
super(comment);
}
@Override
public int getApproximateSize() {
return super.getCommentFieldApproximateSize();
}
@Override
public String toString() {
return toStringHelper().toString();
}
@Override
public boolean equals(Object o) {
if (!(o instanceof HumanComment)) {
return false;
}
return super.equals(o);
}
@Override
public int hashCode() {
return super.hashCode();
}
}

View File

@@ -42,7 +42,8 @@ public final class RobotComment extends Comment {
@Override
public int getApproximateSize() {
int approximateSize = super.getApproximateSize() + nullableLength(robotId, robotRunId, url);
int approximateSize =
super.getCommentFieldApproximateSize() + nullableLength(robotId, robotRunId, url);
approximateSize +=
properties != null
? properties.entrySet().stream()
@@ -66,4 +67,23 @@ public final class RobotComment extends Comment {
.add("fixSuggestions", Objects.toString(fixSuggestions, ""))
.toString();
}
@Override
public boolean equals(Object o) {
if (!(o instanceof RobotComment)) {
return false;
}
RobotComment c = (RobotComment) o;
return super.equals(o)
&& Objects.equals(robotId, c.robotId)
&& Objects.equals(robotRunId, c.robotRunId)
&& Objects.equals(url, c.url)
&& Objects.equals(properties, c.properties)
&& Objects.equals(fixSuggestions, c.fixSuggestions);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), robotId, robotRunId, url, properties, fixSuggestions);
}
}

View File

@@ -18,7 +18,7 @@ import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import com.google.common.collect.PeekingIterator;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -60,7 +60,7 @@ public class HtmlParser {
* @return list of MailComments parsed from the html part of the email
*/
public static List<MailComment> parse(
MailMessage email, Collection<Comment> comments, String changeUrl) {
MailMessage email, Collection<HumanComment> comments, String changeUrl) {
// TODO(hiesel) Add support for Gmail Mobile
// TODO(hiesel) Add tests for other popular email clients
@@ -71,10 +71,10 @@ public class HtmlParser {
// Gerrit as these are generally more reliable then the text captions.
List<MailComment> parsedComments = new ArrayList<>();
Document d = Jsoup.parse(email.htmlContent());
PeekingIterator<Comment> iter = Iterators.peekingIterator(comments.iterator());
PeekingIterator<HumanComment> iter = Iterators.peekingIterator(comments.iterator());
String lastEncounteredFileName = null;
Comment lastEncounteredComment = null;
HumanComment lastEncounteredComment = null;
for (Element e : d.body().getAllElements()) {
String elementName = e.tagName();
boolean isInBlockQuote =
@@ -91,7 +91,7 @@ public class HtmlParser {
if (!iter.hasNext()) {
continue;
}
Comment perspectiveComment = iter.peek();
HumanComment perspectiveComment = iter.peek();
if (href.equals(ParserUtil.filePath(changeUrl, perspectiveComment))) {
if (lastEncounteredFileName == null
|| !lastEncounteredFileName.equals(perspectiveComment.key.filename)) {

View File

@@ -14,7 +14,7 @@
package com.google.gerrit.mail;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import java.util.Objects;
/** A comment parsed from inbound email */
@@ -26,7 +26,7 @@ public class MailComment {
}
CommentType type;
Comment inReplyTo;
HumanComment inReplyTo;
String fileName;
String message;
boolean isLink;
@@ -34,7 +34,7 @@ public class MailComment {
public MailComment() {}
public MailComment(
String message, String fileName, Comment inReplyTo, CommentType type, boolean isLink) {
String message, String fileName, HumanComment inReplyTo, CommentType type, boolean isLink) {
this.message = message;
this.fileName = fileName;
this.inReplyTo = inReplyTo;
@@ -46,7 +46,7 @@ public class MailComment {
return type;
}
public Comment getInReplyTo() {
public HumanComment getInReplyTo() {
return inReplyTo;
}

View File

@@ -18,7 +18,7 @@ import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Iterators;
import com.google.common.collect.PeekingIterator;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -31,15 +31,15 @@ public class TextParser {
* Parses comments from plaintext email.
*
* @param email @param email the message as received from the email service
* @param comments list of {@link Comment}s previously persisted on the change that caused the
* original notification email to be sent out. Ordering must be the same as in the outbound
* email
* @param comments list of {@link HumanComment}s previously persisted on the change that caused
* the original notification email to be sent out. Ordering must be the same as in the
* outbound email
* @param changeUrl canonical change url that points to the change on this Gerrit instance.
* Example: https://go-review.googlesource.com/#/c/91570
* @return list of MailComments parsed from the plaintext part of the email
*/
public static List<MailComment> parse(
MailMessage email, Collection<Comment> comments, String changeUrl) {
MailMessage email, Collection<HumanComment> comments, String changeUrl) {
String body = email.textContent();
// Replace CR-LF by \n
body = body.replace("\r\n", "\n");
@@ -62,11 +62,11 @@ public class TextParser {
body = body.replace(doubleQuotePattern, singleQuotePattern);
}
PeekingIterator<Comment> iter = Iterators.peekingIterator(comments.iterator());
PeekingIterator<HumanComment> iter = Iterators.peekingIterator(comments.iterator());
MailComment currentComment = null;
String lastEncounteredFileName = null;
Comment lastEncounteredComment = null;
HumanComment lastEncounteredComment = null;
for (String line : Splitter.on('\n').split(body)) {
if (line.equals(">")) {
// Skip empty lines
@@ -89,7 +89,7 @@ public class TextParser {
if (!iter.hasNext()) {
continue;
}
Comment perspectiveComment = iter.peek();
HumanComment perspectiveComment = iter.peek();
if (line.equals(ParserUtil.filePath(changeUrl, perspectiveComment))) {
if (lastEncounteredFileName == null
|| !lastEncounteredFileName.equals(perspectiveComment.key.filename)) {

View File

@@ -28,6 +28,7 @@ import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.RefNames;
@@ -116,7 +117,7 @@ public class CommentsUtil {
this.serverId = serverId;
}
public Comment newComment(
public HumanComment newHumanComment(
ChangeContext ctx,
String path,
PatchSet.Id psId,
@@ -132,15 +133,15 @@ public class CommentsUtil {
} else {
// Inherit unresolved value from inReplyTo comment if not specified.
Comment.Key key = new Comment.Key(parentUuid, path, psId.get());
Optional<Comment> parent = getPublished(ctx.getNotes(), key);
Optional<HumanComment> parent = getPublishedHumanComment(ctx.getNotes(), key);
if (!parent.isPresent()) {
throw new UnprocessableEntityException("Invalid parentUuid supplied for comment");
}
unresolved = parent.get().unresolved;
}
}
Comment c =
new Comment(
HumanComment c =
new HumanComment(
new Comment.Key(ChangeUtil.messageUuid(), path, psId.get()),
ctx.getUser().getAccountId(),
ctx.getWhen(),
@@ -175,19 +176,21 @@ public class CommentsUtil {
return c;
}
public Optional<Comment> getPublished(ChangeNotes notes, Comment.Key key) {
return publishedByChange(notes).stream().filter(c -> key.equals(c.key)).findFirst();
public Optional<HumanComment> getPublishedHumanComment(ChangeNotes notes, Comment.Key key) {
return publishedHumanCommentsByChange(notes).stream()
.filter(c -> key.equals(c.key))
.findFirst();
}
public Optional<Comment> getDraft(ChangeNotes notes, IdentifiedUser user, Comment.Key key) {
public Optional<HumanComment> getDraft(ChangeNotes notes, IdentifiedUser user, Comment.Key key) {
return draftByChangeAuthor(notes, user.getAccountId()).stream()
.filter(c -> key.equals(c.key))
.findFirst();
}
public List<Comment> publishedByChange(ChangeNotes notes) {
public List<HumanComment> publishedHumanCommentsByChange(ChangeNotes notes) {
notes.load();
return sort(Lists.newArrayList(notes.getComments().values()));
return sort(Lists.newArrayList(notes.getHumanComments().values()));
}
public List<RobotComment> robotCommentsByChange(ChangeNotes notes) {
@@ -195,8 +198,8 @@ public class CommentsUtil {
return sort(Lists.newArrayList(notes.getRobotComments().values()));
}
public List<Comment> draftByChange(ChangeNotes notes) {
List<Comment> comments = new ArrayList<>();
public List<HumanComment> draftByChange(ChangeNotes notes) {
List<HumanComment> comments = new ArrayList<>();
for (Ref ref : getDraftRefs(notes.getChangeId())) {
Account.Id account = Account.Id.fromRefSuffix(ref.getName());
if (account != null) {
@@ -206,8 +209,8 @@ public class CommentsUtil {
return sort(comments);
}
public List<Comment> byPatchSet(ChangeNotes notes, PatchSet.Id psId) {
List<Comment> comments = new ArrayList<>();
public List<HumanComment> byPatchSet(ChangeNotes notes, PatchSet.Id psId) {
List<HumanComment> comments = new ArrayList<>();
comments.addAll(publishedByPatchSet(notes, psId));
for (Ref ref : getDraftRefs(notes.getChangeId())) {
@@ -219,13 +222,13 @@ public class CommentsUtil {
return sort(comments);
}
public List<Comment> publishedByChangeFile(ChangeNotes notes, String file) {
return commentsOnFile(notes.load().getComments().values(), file);
public List<HumanComment> publishedByChangeFile(ChangeNotes notes, String file) {
return commentsOnFile(notes.load().getHumanComments().values(), file);
}
public List<Comment> publishedByPatchSet(ChangeNotes notes, PatchSet.Id psId) {
public List<HumanComment> publishedByPatchSet(ChangeNotes notes, PatchSet.Id psId) {
return removeCommentsOnAncestorOfCommitMessage(
commentsOnPatchSet(notes.load().getComments().values(), psId));
commentsOnPatchSet(notes.load().getHumanComments().values(), psId));
}
public List<RobotComment> robotCommentsByPatchSet(ChangeNotes notes, PatchSet.Id psId) {
@@ -288,29 +291,31 @@ public class CommentsUtil {
* auto-merge was done. From that time there may still be comments on the auto-merge commit
* message and those we want to filter out.
*/
private List<Comment> removeCommentsOnAncestorOfCommitMessage(List<Comment> list) {
private List<HumanComment> removeCommentsOnAncestorOfCommitMessage(List<HumanComment> list) {
return list.stream()
.filter(c -> c.side != 0 || !Patch.COMMIT_MSG.equals(c.key.filename))
.collect(toList());
}
public List<Comment> draftByPatchSetAuthor(
public List<HumanComment> draftByPatchSetAuthor(
PatchSet.Id psId, Account.Id author, ChangeNotes notes) {
return commentsOnPatchSet(notes.load().getDraftComments(author).values(), psId);
}
public List<Comment> draftByChangeFileAuthor(ChangeNotes notes, String file, Account.Id author) {
public List<HumanComment> draftByChangeFileAuthor(
ChangeNotes notes, String file, Account.Id author) {
return commentsOnFile(notes.load().getDraftComments(author).values(), file);
}
public List<Comment> draftByChangeAuthor(ChangeNotes notes, Account.Id author) {
List<Comment> comments = new ArrayList<>();
public List<HumanComment> draftByChangeAuthor(ChangeNotes notes, Account.Id author) {
List<HumanComment> comments = new ArrayList<>();
comments.addAll(notes.getDraftComments(author).values());
return sort(comments);
}
public void putComments(ChangeUpdate update, Comment.Status status, Iterable<Comment> comments) {
for (Comment c : comments) {
public void putHumanComments(
ChangeUpdate update, HumanComment.Status status, Iterable<HumanComment> comments) {
for (HumanComment c : comments) {
update.putComment(status, c);
}
}
@@ -321,8 +326,8 @@ public class CommentsUtil {
}
}
public void deleteComments(ChangeUpdate update, Iterable<Comment> comments) {
for (Comment c : comments) {
public void deleteHumanComments(ChangeUpdate update, Iterable<HumanComment> comments) {
for (HumanComment c : comments) {
update.deleteComment(c);
}
}
@@ -332,9 +337,10 @@ public class CommentsUtil {
update.deleteCommentByRewritingHistory(commentKey.uuid, newMessage);
}
private static List<Comment> commentsOnFile(Collection<Comment> allComments, String file) {
List<Comment> result = new ArrayList<>(allComments.size());
for (Comment c : allComments) {
private static List<HumanComment> commentsOnFile(
Collection<HumanComment> allComments, String file) {
List<HumanComment> result = new ArrayList<>(allComments.size());
for (HumanComment c : allComments) {
String currentFilename = c.key.filename;
if (currentFilename.equals(file)) {
result.add(c);

View File

@@ -20,8 +20,7 @@ import static java.util.stream.Collectors.toSet;
import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.Comment.Status;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.validators.CommentForValidation;
@@ -60,7 +59,7 @@ public class PublishCommentUtil {
public void publish(
ChangeContext ctx,
ChangeUpdate changeUpdate,
Collection<Comment> draftComments,
Collection<HumanComment> draftComments,
@Nullable String tag) {
ChangeNotes notes = ctx.getNotes();
checkArgument(notes != null);
@@ -70,8 +69,8 @@ public class PublishCommentUtil {
Map<PatchSet.Id, PatchSet> patchSets =
psUtil.getAsMap(notes, draftComments.stream().map(d -> psId(notes, d)).collect(toSet()));
Set<Comment> commentsToPublish = new HashSet<>();
for (Comment draftComment : draftComments) {
Set<HumanComment> commentsToPublish = new HashSet<>();
for (HumanComment draftComment : draftComments) {
PatchSet.Id psIdOfDraftComment = psId(notes, draftComment);
PatchSet ps = patchSets.get(psIdOfDraftComment);
if (ps == null) {
@@ -109,10 +108,10 @@ public class PublishCommentUtil {
}
commentsToPublish.add(draftComment);
}
commentsUtil.putComments(changeUpdate, Status.PUBLISHED, commentsToPublish);
commentsUtil.putHumanComments(changeUpdate, HumanComment.Status.PUBLISHED, commentsToPublish);
}
private static PatchSet.Id psId(ChangeNotes notes, Comment c) {
private static PatchSet.Id psId(ChangeNotes notes, HumanComment c) {
return PatchSet.id(notes.getChangeId(), c.key.patchSetId);
}

View File

@@ -16,7 +16,7 @@ package com.google.gerrit.server;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.exceptions.StorageException;
@@ -58,7 +58,7 @@ public class PublishCommentsOp implements BatchUpdateOp {
private final PatchSet.Id psId;
private final PublishCommentUtil publishCommentUtil;
private List<Comment> comments = new ArrayList<>();
private List<HumanComment> comments = new ArrayList<>();
private ChangeMessage message;
private IdentifiedUser user;

View File

@@ -20,7 +20,7 @@ import com.google.gerrit.extensions.api.changes.CommentApi;
import com.google.gerrit.extensions.api.changes.DeleteCommentInput;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.change.CommentResource;
import com.google.gerrit.server.change.HumanCommentResource;
import com.google.gerrit.server.restapi.change.DeleteComment;
import com.google.gerrit.server.restapi.change.GetComment;
import com.google.inject.Inject;
@@ -28,16 +28,16 @@ import com.google.inject.assistedinject.Assisted;
class CommentApiImpl implements CommentApi {
interface Factory {
CommentApiImpl create(CommentResource c);
CommentApiImpl create(HumanCommentResource c);
}
private final GetComment getComment;
private final DeleteComment deleteComment;
private final CommentResource comment;
private final HumanCommentResource comment;
@Inject
CommentApiImpl(
GetComment getComment, DeleteComment deleteComment, @Assisted CommentResource comment) {
GetComment getComment, DeleteComment deleteComment, @Assisted HumanCommentResource comment) {
this.getComment = getComment;
this.deleteComment = deleteComment;
this.comment = comment;

View File

@@ -15,7 +15,7 @@
package com.google.gerrit.server.change;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.extensions.restapi.RestResource;
import com.google.gerrit.extensions.restapi.RestView;
@@ -27,9 +27,9 @@ public class DraftCommentResource implements RestResource {
new TypeLiteral<RestView<DraftCommentResource>>() {};
private final RevisionResource rev;
private final Comment comment;
private final HumanComment comment;
public DraftCommentResource(RevisionResource rev, Comment c) {
public DraftCommentResource(RevisionResource rev, HumanComment c) {
this.rev = rev;
this.comment = c;
}
@@ -46,7 +46,7 @@ public class DraftCommentResource implements RestResource {
return rev.getPatchSet();
}
public Comment getComment() {
public HumanComment getComment() {
return comment;
}

View File

@@ -65,7 +65,7 @@ public class EmailReviewComments implements Runnable, RequestContext {
PatchSet patchSet,
IdentifiedUser user,
ChangeMessage message,
List<Comment> comments,
List<? extends Comment> comments,
String patchSetComment,
List<LabelVote> labels,
RepoView repoView);
@@ -82,7 +82,7 @@ public class EmailReviewComments implements Runnable, RequestContext {
private final PatchSet patchSet;
private final IdentifiedUser user;
private final ChangeMessage message;
private final List<Comment> comments;
private final List<? extends Comment> comments;
private final String patchSetComment;
private final List<LabelVote> labels;
private final RepoView repoView;
@@ -99,7 +99,7 @@ public class EmailReviewComments implements Runnable, RequestContext {
@Assisted PatchSet patchSet,
@Assisted IdentifiedUser user,
@Assisted ChangeMessage message,
@Assisted List<Comment> comments,
@Assisted List<? extends Comment> comments,
@Nullable @Assisted String patchSetComment,
@Assisted List<LabelVote> labels,
@Assisted RepoView repoView) {

View File

@@ -15,20 +15,20 @@
package com.google.gerrit.server.change;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.extensions.restapi.RestResource;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.inject.TypeLiteral;
public class CommentResource implements RestResource {
public static final TypeLiteral<RestView<CommentResource>> COMMENT_KIND =
new TypeLiteral<RestView<CommentResource>>() {};
public class HumanCommentResource implements RestResource {
public static final TypeLiteral<RestView<HumanCommentResource>> COMMENT_KIND =
new TypeLiteral<RestView<HumanCommentResource>>() {};
private final RevisionResource rev;
private final Comment comment;
private final HumanComment comment;
public CommentResource(RevisionResource rev, Comment c) {
public HumanCommentResource(RevisionResource rev, HumanComment c) {
this.rev = rev;
this.comment = c;
}
@@ -37,7 +37,7 @@ public class CommentResource implements RestResource {
return rev.getPatchSet();
}
public Comment getComment() {
public HumanComment getComment() {
return comment;
}

View File

@@ -28,7 +28,7 @@ import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.PatchSetApproval;
import com.google.gerrit.entities.UserIdentity;
@@ -380,8 +380,8 @@ public class EventFactory {
}
public void addPatchSetComments(
PatchSetAttribute patchSetAttribute, Collection<Comment> comments) {
for (Comment comment : comments) {
PatchSetAttribute patchSetAttribute, Collection<HumanComment> comments) {
for (HumanComment comment : comments) {
if (comment.key.patchSetId == patchSetAttribute.number) {
if (patchSetAttribute.comments == null) {
patchSetAttribute.comments = new ArrayList<>();
@@ -547,7 +547,7 @@ public class EventFactory {
return a;
}
public PatchSetCommentAttribute asPatchSetLineAttribute(Comment c) {
public PatchSetCommentAttribute asPatchSetLineAttribute(HumanComment c) {
PatchSetCommentAttribute a = new PatchSetCommentAttribute();
a.reviewer = asAccountAttribute(c.author.getId());
a.file = c.key.filename;

View File

@@ -69,7 +69,7 @@ import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.BooleanProjectConfig;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.PatchSetInfo;
import com.google.gerrit.entities.Project;
@@ -2022,7 +2022,7 @@ class ReceiveCommits {
}
if (magicBranch != null && magicBranch.shouldPublishComments()) {
List<Comment> drafts =
List<HumanComment> drafts =
commentsUtil.draftByChangeAuthor(
notesFactory.createChecked(change), user.getAccountId());
ImmutableList<CommentForValidation> draftsForValidation =

View File

@@ -45,7 +45,7 @@ public class CommentCountValidator implements CommentValidator {
ChangeNotes notes =
notesFactory.createChecked(Project.nameKey(ctx.getProject()), Change.id(ctx.getChangeId()));
int numExistingCommentsAndChangeMessages =
notes.getComments().size()
notes.getHumanComments().size()
+ notes.getRobotComments().size()
+ notes.getChangeMessages().size();
if (!comments.isEmpty()

View File

@@ -51,7 +51,7 @@ public class CommentCumulativeSizeValidator implements CommentValidator {
notesFactory.createChecked(Project.nameKey(ctx.getProject()), Change.id(ctx.getChangeId()));
int existingCumulativeSize =
Stream.concat(
notes.getComments().values().stream(),
notes.getHumanComments().values().stream(),
notes.getRobotComments().values().stream())
.mapToInt(Comment::getApproximateSize)
.sum()

View File

@@ -24,7 +24,7 @@ import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.exceptions.StorageException;
@@ -257,7 +257,7 @@ public class MailProcessor {
// Get all comments; filter and sort them to get the original list of
// comments from the outbound email.
// TODO(hiesel) Also filter by original comment author.
Collection<Comment> comments =
Collection<HumanComment> comments =
cd.publishedComments().stream()
.filter(c -> (c.writtenOn.getTime() / 1000) == (metadata.timestamp.getTime() / 1000))
.sorted(CommentsUtil.COMMENT_ORDER)
@@ -319,7 +319,7 @@ public class MailProcessor {
private final List<MailComment> parsedComments;
private final String tag;
private ChangeMessage changeMessage;
private List<Comment> comments;
private List<HumanComment> comments;
private PatchSet patchSet;
private ChangeNotes notes;
@@ -349,8 +349,10 @@ public class MailProcessor {
comments.add(
persistentCommentFromMailComment(ctx, c, targetPatchSetForComment(ctx, c, patchSet)));
}
commentsUtil.putComments(
ctx.getUpdate(ctx.getChange().currentPatchSetId()), Comment.Status.PUBLISHED, comments);
commentsUtil.putHumanComments(
ctx.getUpdate(ctx.getChange().currentPatchSetId()),
HumanComment.Status.PUBLISHED,
comments);
return true;
}
@@ -416,7 +418,7 @@ public class MailProcessor {
return current;
}
private Comment persistentCommentFromMailComment(
private HumanComment persistentCommentFromMailComment(
ChangeContext ctx, MailComment mailComment, PatchSet patchSetForComment)
throws UnprocessableEntityException, PatchListNotAvailableException {
String fileName;
@@ -431,8 +433,8 @@ public class MailProcessor {
side = Side.REVISION;
}
Comment comment =
commentsUtil.newComment(
HumanComment comment =
commentsUtil.newHumanComment(
ctx,
fileName,
patchSetForComment.id(),

View File

@@ -22,6 +22,7 @@ import com.google.gerrit.common.data.FilenameComparator;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.KeyUtil;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.Project;
@@ -114,7 +115,7 @@ public class CommentSender extends ReplyToChangeSender {
}
}
private List<Comment> inlineComments = Collections.emptyList();
private List<? extends Comment> inlineComments = Collections.emptyList();
private String patchSetComment;
private List<LabelVote> labels = Collections.emptyList();
private final CommentsUtil commentsUtil;
@@ -136,7 +137,7 @@ public class CommentSender extends ReplyToChangeSender {
this.replyToAddress = cfg.getString("sendemail", null, "replyToAddress");
}
public void setComments(List<Comment> comments) {
public void setComments(List<? extends Comment> comments) {
inlineComments = comments;
}
@@ -244,23 +245,21 @@ public class CommentSender extends ReplyToChangeSender {
/** Get the set of accounts whose comments have been replied to in this email. */
private HashSet<Account.Id> getReplyAccounts() {
HashSet<Account.Id> replyAccounts = new HashSet<>();
// Track visited parent UUIDs to avoid cycles.
HashSet<String> visitedUuids = new HashSet<>();
for (Comment comment : inlineComments) {
visitedUuids.add(comment.key.uuid);
// Traverse the parent relation to the top of the comment thread.
Comment current = comment;
while (current.parentUuid != null && !visitedUuids.contains(current.parentUuid)) {
Optional<Comment> optParent = getParent(current);
Optional<HumanComment> optParent = getParent(current);
if (!optParent.isPresent()) {
// There is a parent UUID, but it cannot be loaded, break from the comment thread.
break;
}
Comment parent = optParent.get();
HumanComment parent = optParent.get();
replyAccounts.add(parent.author.getId());
visitedUuids.add(current.parentUuid);
current = parent;
@@ -307,14 +306,13 @@ public class CommentSender extends ReplyToChangeSender {
* @return an optional comment that will be present if the given comment has a parent, and is
* empty if it does not.
*/
private Optional<Comment> getParent(Comment child) {
private Optional<HumanComment> getParent(Comment child) {
if (child.parentUuid == null) {
return Optional.empty();
}
Comment.Key key = new Comment.Key(child.parentUuid, child.key.filename, child.key.patchSetId);
try {
return commentsUtil.getPublished(changeData.notes(), key);
return commentsUtil.getPublishedHumanComment(changeData.notes(), key);
} catch (StorageException e) {
logger.atWarning().log("Could not find the parent of this comment: %s", child);
return Optional.empty();
@@ -448,7 +446,7 @@ public class CommentSender extends ReplyToChangeSender {
// If the comment has a quote, don't bother loading the parent message.
if (!hasQuote(blocks)) {
// Set parent comment info.
Optional<Comment> parent = getParent(comment);
Optional<HumanComment> parent = getParent(comment);
if (parent.isPresent()) {
commentData.put("parentMessage", getShortenedCommentMessage(parent.get()));
}

View File

@@ -22,6 +22,7 @@ import com.google.auto.value.AutoValue;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.exceptions.StorageException;
@@ -82,13 +83,13 @@ public class ChangeDraftUpdate extends AbstractChangeUpdate {
FIXED
}
private static Key key(Comment c) {
private static Key key(HumanComment c) {
return new AutoValue_ChangeDraftUpdate_Key(c.getCommitId(), c.key);
}
private final AllUsersName draftsProject;
private List<Comment> put = new ArrayList<>();
private List<HumanComment> put = new ArrayList<>();
private Map<Key, DeleteReason> delete = new HashMap<>();
@AssistedInject
@@ -119,7 +120,7 @@ public class ChangeDraftUpdate extends AbstractChangeUpdate {
this.draftsProject = allUsers;
}
public void putComment(Comment c) {
public void putComment(HumanComment c) {
checkState(!put.contains(c), "comment already added");
verifyComment(c);
put.add(c);
@@ -128,7 +129,7 @@ public class ChangeDraftUpdate extends AbstractChangeUpdate {
/**
* Marks a comment for deletion. Called when the comment is deleted because the user published it.
*/
public void markCommentPublished(Comment c) {
public void markCommentPublished(HumanComment c) {
checkState(!delete.containsKey(key(c)), "comment already marked for deletion");
verifyComment(c);
delete.put(key(c), DeleteReason.PUBLISHED);
@@ -137,7 +138,7 @@ public class ChangeDraftUpdate extends AbstractChangeUpdate {
/**
* Marks a comment for deletion. Called when the comment is deleted because the user removed it.
*/
public void deleteComment(Comment c) {
public void deleteComment(HumanComment c) {
checkState(!delete.containsKey(key(c)), "comment already marked for deletion");
verifyComment(c);
delete.put(key(c), DeleteReason.DELETED);
@@ -191,7 +192,7 @@ public class ChangeDraftUpdate extends AbstractChangeUpdate {
RevisionNoteMap<ChangeRevisionNote> rnm = getRevisionNoteMap(rw, curr);
RevisionNoteBuilder.Cache cache = new RevisionNoteBuilder.Cache(rnm);
for (Comment c : put) {
for (HumanComment c : put) {
if (!delete.keySet().contains(key(c))) {
cache.get(c.getCommitId()).putComment(c);
}
@@ -259,7 +260,7 @@ public class ChangeDraftUpdate extends AbstractChangeUpdate {
// Even though reading from changes might not be enabled, we need to
// parse any existing revision notes so we can merge them.
return RevisionNoteMap.parse(
noteUtil.getChangeNoteJson(), rw.getObjectReader(), noteMap, Comment.Status.DRAFT);
noteUtil.getChangeNoteJson(), rw.getObjectReader(), noteMap, HumanComment.Status.DRAFT);
}
@Override

View File

@@ -45,6 +45,7 @@ import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.PatchSetApproval;
import com.google.gerrit.entities.Project;
@@ -435,14 +436,14 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
}
/** @return inline comments on each revision. */
public ImmutableListMultimap<ObjectId, Comment> getComments() {
public ImmutableListMultimap<ObjectId, HumanComment> getHumanComments() {
return state.publishedComments();
}
public ImmutableSet<Comment.Key> getCommentKeys() {
if (commentKeys == null) {
ImmutableSet.Builder<Comment.Key> b = ImmutableSet.builder();
for (Comment c : getComments().values()) {
for (Comment c : getHumanComments().values()) {
b.add(new Comment.Key(c.key));
}
commentKeys = b.build();
@@ -454,11 +455,11 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
return state.updateCount();
}
public ImmutableListMultimap<ObjectId, Comment> getDraftComments(Account.Id author) {
public ImmutableListMultimap<ObjectId, HumanComment> getDraftComments(Account.Id author) {
return getDraftComments(author, null);
}
public ImmutableListMultimap<ObjectId, Comment> getDraftComments(
public ImmutableListMultimap<ObjectId, HumanComment> getDraftComments(
Account.Id author, @Nullable Ref ref) {
loadDraftComments(author, ref);
// Filter out any zombie draft comments. These are drafts that are also in
@@ -502,7 +503,7 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
return robotCommentNotes;
}
public boolean containsComment(Comment c) {
public boolean containsComment(HumanComment c) {
if (containsCommentPublished(c)) {
return true;
}
@@ -511,7 +512,7 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
}
public boolean containsCommentPublished(Comment c) {
for (Comment l : getComments().values()) {
for (Comment l : getHumanComments().values()) {
if (c.key.equals(l.key)) {
return true;
}

View File

@@ -61,7 +61,7 @@ import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AttentionSetUpdate;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.LabelId;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.PatchSetApproval;
@@ -121,7 +121,7 @@ class ChangeNotesParser {
private final List<AssigneeStatusUpdate> assigneeUpdates;
private final List<SubmitRecord> submitRecords;
private final ListMultimap<ObjectId, Comment> comments;
private final ListMultimap<ObjectId, HumanComment> humanComments;
private final Map<PatchSet.Id, PatchSet.Builder> patchSets;
private final Set<PatchSet.Id> deletedPatchSets;
private final Map<PatchSet.Id, PatchSetState> patchSetStates;
@@ -178,7 +178,7 @@ class ChangeNotesParser {
assigneeUpdates = new ArrayList<>();
submitRecords = Lists.newArrayListWithExpectedSize(1);
allChangeMessages = new ArrayList<>();
comments = MultimapBuilder.hashKeys().arrayListValues().build();
humanComments = MultimapBuilder.hashKeys().arrayListValues().build();
patchSets = new HashMap<>();
deletedPatchSets = new HashSet<>();
patchSetStates = new HashMap<>();
@@ -249,7 +249,7 @@ class ChangeNotesParser {
assigneeUpdates,
submitRecords,
buildAllMessages(),
comments,
humanComments,
firstNonNull(isPrivate, false),
firstNonNull(workInProgress, false),
firstNonNull(hasReviewStarted, true),
@@ -735,12 +735,12 @@ class ChangeNotesParser {
ChangeNotesCommit tipCommit = walk.parseCommit(tip);
revisionNoteMap =
RevisionNoteMap.parse(
changeNoteJson, reader, NoteMap.read(reader, tipCommit), Comment.Status.PUBLISHED);
changeNoteJson, reader, NoteMap.read(reader, tipCommit), HumanComment.Status.PUBLISHED);
Map<ObjectId, ChangeRevisionNote> rns = revisionNoteMap.revisionNotes;
for (Map.Entry<ObjectId, ChangeRevisionNote> e : rns.entrySet()) {
for (Comment c : e.getValue().getEntities()) {
comments.put(e.getKey(), c);
for (HumanComment c : e.getValue().getEntities()) {
humanComments.put(e.getKey(), c);
}
}
@@ -1055,7 +1055,7 @@ class ChangeNotesParser {
pruneEntitiesForMissingPatchSets(allChangeMessages, ChangeMessage::getPatchSetId, missing);
pruned +=
pruneEntitiesForMissingPatchSets(
comments.values(), c -> PatchSet.id(id, c.key.patchSetId), missing);
humanComments.values(), c -> PatchSet.id(id, c.key.patchSetId), missing);
pruned +=
pruneEntitiesForMissingPatchSets(
approvals.values(), psa -> psa.key().patchSetId(), missing);

View File

@@ -39,7 +39,7 @@ import com.google.gerrit.entities.AttentionSetUpdate;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.PatchSetApproval;
import com.google.gerrit.entities.Project;
@@ -123,7 +123,7 @@ public abstract class ChangeNotesState {
List<AssigneeStatusUpdate> assigneeUpdates,
List<SubmitRecord> submitRecords,
List<ChangeMessage> changeMessages,
ListMultimap<ObjectId, Comment> publishedComments,
ListMultimap<ObjectId, HumanComment> publishedComments,
boolean isPrivate,
boolean workInProgress,
boolean reviewStarted,
@@ -314,7 +314,7 @@ public abstract class ChangeNotesState {
abstract ImmutableList<ChangeMessage> changeMessages();
abstract ImmutableListMultimap<ObjectId, Comment> publishedComments();
abstract ImmutableListMultimap<ObjectId, HumanComment> publishedComments();
abstract int updateCount();
@@ -427,7 +427,7 @@ public abstract class ChangeNotesState {
abstract Builder changeMessages(List<ChangeMessage> changeMessages);
abstract Builder publishedComments(ListMultimap<ObjectId, Comment> publishedComments);
abstract Builder publishedComments(ListMultimap<ObjectId, HumanComment> publishedComments);
abstract Builder updateCount(int updateCount);
@@ -634,8 +634,8 @@ public abstract class ChangeNotesState {
.collect(toImmutableList()))
.publishedComments(
proto.getPublishedCommentList().stream()
.map(r -> GSON.fromJson(r, Comment.class))
.collect(toImmutableListMultimap(Comment::getCommitId, c -> c)))
.map(r -> GSON.fromJson(r, HumanComment.class))
.collect(toImmutableListMultimap(HumanComment::getCommitId, c -> c)))
.updateCount(proto.getUpdateCount());
return b.build();
}

View File

@@ -16,7 +16,7 @@ package com.google.gerrit.server.notedb;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -29,13 +29,13 @@ import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.util.MutableInteger;
/** Implements the parsing of comment data, handling JSON decoding and push certificates. */
class ChangeRevisionNote extends RevisionNote<Comment> {
class ChangeRevisionNote extends RevisionNote<HumanComment> {
private final ChangeNoteJson noteJson;
private final Comment.Status status;
private final HumanComment.Status status;
private String pushCert;
ChangeRevisionNote(
ChangeNoteJson noteJson, ObjectReader reader, ObjectId noteId, Comment.Status status) {
ChangeNoteJson noteJson, ObjectReader reader, ObjectId noteId, HumanComment.Status status) {
super(reader, noteId);
this.noteJson = noteJson;
this.status = status;
@@ -47,12 +47,13 @@ class ChangeRevisionNote extends RevisionNote<Comment> {
}
@Override
protected List<Comment> parse(byte[] raw, int offset) throws IOException, ConfigInvalidException {
protected List<HumanComment> parse(byte[] raw, int offset)
throws IOException, ConfigInvalidException {
MutableInteger p = new MutableInteger();
p.value = offset;
RevisionNoteData data = parseJson(noteJson, raw, p.value);
if (status == Comment.Status.PUBLISHED) {
HumanCommentsRevisionNoteData data = parseJson(noteJson, raw, p.value);
if (status == HumanComment.Status.PUBLISHED) {
pushCert = data.pushCert;
} else {
pushCert = null;
@@ -60,11 +61,11 @@ class ChangeRevisionNote extends RevisionNote<Comment> {
return data.comments;
}
private RevisionNoteData parseJson(ChangeNoteJson noteUtil, byte[] raw, int offset)
private HumanCommentsRevisionNoteData parseJson(ChangeNoteJson noteUtil, byte[] raw, int offset)
throws IOException {
try (InputStream is = new ByteArrayInputStream(raw, offset, raw.length - offset);
Reader r = new InputStreamReader(is, UTF_8)) {
return noteUtil.getGson().fromJson(r, RevisionNoteData.class);
return noteUtil.getGson().fromJson(r, HumanCommentsRevisionNoteData.class);
}
}
}

View File

@@ -58,6 +58,7 @@ import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AttentionSetUpdate;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RobotComment;
import com.google.gerrit.entities.SubmissionId;
@@ -122,7 +123,7 @@ public class ChangeUpdate extends AbstractChangeUpdate {
private final Table<String, Account.Id, Optional<Short>> approvals;
private final Map<Account.Id, ReviewerStateInternal> reviewers = new LinkedHashMap<>();
private final Map<Address, ReviewerStateInternal> reviewersByEmail = new LinkedHashMap<>();
private final List<Comment> comments = new ArrayList<>();
private final List<HumanComment> comments = new ArrayList<>();
private String commitSubject;
private String subject;
@@ -289,10 +290,10 @@ public class ChangeUpdate extends AbstractChangeUpdate {
this.psDescription = psDescription;
}
public void putComment(Comment.Status status, Comment c) {
public void putComment(HumanComment.Status status, HumanComment c) {
verifyComment(c);
createDraftUpdateIfNull();
if (status == Comment.Status.DRAFT) {
if (status == HumanComment.Status.DRAFT) {
draftUpdate.putComment(c);
} else {
comments.add(c);
@@ -306,7 +307,7 @@ public class ChangeUpdate extends AbstractChangeUpdate {
robotCommentUpdate.putComment(c);
}
public void deleteComment(Comment c) {
public void deleteComment(HumanComment c) {
verifyComment(c);
createDraftUpdateIfNull().deleteComment(c);
}
@@ -475,7 +476,7 @@ public class ChangeUpdate extends AbstractChangeUpdate {
RevisionNoteMap<ChangeRevisionNote> rnm = getRevisionNoteMap(rw, curr);
RevisionNoteBuilder.Cache cache = new RevisionNoteBuilder.Cache(rnm);
for (Comment c : comments) {
for (HumanComment c : comments) {
c.tag = tag;
cache.get(c.getCommitId()).putComment(c);
}
@@ -512,7 +513,7 @@ public class ChangeUpdate extends AbstractChangeUpdate {
// Even though reading from changes might not be enabled, we need to
// parse any existing revision notes so we can merge them.
return RevisionNoteMap.parse(
noteUtil.getChangeNoteJson(), rw.getObjectReader(), noteMap, Comment.Status.PUBLISHED);
noteUtil.getChangeNoteJson(), rw.getObjectReader(), noteMap, HumanComment.Status.PUBLISHED);
}
private void checkComments(

View File

@@ -15,14 +15,13 @@
package com.google.gerrit.server.notedb;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.gerrit.entities.Comment.Status;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import com.google.common.annotations.VisibleForTesting;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.RefNames;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -94,14 +93,14 @@ public class DeleteCommentRewriter implements NoteDbRewriter {
ObjectReader reader = revWalk.getObjectReader();
RevCommit newTipCommit = revWalk.next(); // The first commit will not be rewritten.
Map<String, Comment> parentComments =
Map<String, HumanComment> parentComments =
getPublishedComments(noteUtil, reader, NoteMap.read(reader, newTipCommit));
boolean rewrite = false;
RevCommit originalCommit;
while ((originalCommit = revWalk.next()) != null) {
NoteMap noteMap = NoteMap.read(reader, originalCommit);
Map<String, Comment> currComments = getPublishedComments(noteUtil, reader, noteMap);
Map<String, HumanComment> currComments = getPublishedComments(noteUtil, reader, noteMap);
if (!rewrite && currComments.containsKey(uuid)) {
rewrite = true;
@@ -113,8 +112,8 @@ public class DeleteCommentRewriter implements NoteDbRewriter {
continue;
}
List<Comment> putInComments = getPutInComments(parentComments, currComments);
List<Comment> deletedComments = getDeletedComments(parentComments, currComments);
List<HumanComment> putInComments = getPutInComments(parentComments, currComments);
List<HumanComment> deletedComments = getDeletedComments(parentComments, currComments);
newTipCommit =
revWalk.parseCommit(
rewriteCommit(
@@ -130,16 +129,16 @@ public class DeleteCommentRewriter implements NoteDbRewriter {
* the previous commits.
*/
@VisibleForTesting
public static Map<String, Comment> getPublishedComments(
public static Map<String, HumanComment> getPublishedComments(
ChangeNoteJson changeNoteJson, ObjectReader reader, NoteMap noteMap)
throws IOException, ConfigInvalidException {
return RevisionNoteMap.parse(changeNoteJson, reader, noteMap, Status.PUBLISHED).revisionNotes
.values().stream()
return RevisionNoteMap.parse(changeNoteJson, reader, noteMap, HumanComment.Status.PUBLISHED)
.revisionNotes.values().stream()
.flatMap(n -> n.getEntities().stream())
.collect(toMap(c -> c.key.uuid, Function.identity()));
}
public static Map<String, Comment> getPublishedComments(
public static Map<String, HumanComment> getPublishedComments(
ChangeNoteUtil noteUtil, ObjectReader reader, NoteMap noteMap)
throws IOException, ConfigInvalidException {
return getPublishedComments(noteUtil.getChangeNoteJson(), reader, noteMap);
@@ -152,11 +151,12 @@ public class DeleteCommentRewriter implements NoteDbRewriter {
* @param curMap the comment map of the current commit.
* @return The comments put in by the current commit.
*/
private List<Comment> getPutInComments(Map<String, Comment> parMap, Map<String, Comment> curMap) {
List<Comment> comments = new ArrayList<>();
private List<HumanComment> getPutInComments(
Map<String, HumanComment> parMap, Map<String, HumanComment> curMap) {
List<HumanComment> comments = new ArrayList<>();
for (String key : curMap.keySet()) {
if (!parMap.containsKey(key)) {
Comment comment = curMap.get(key);
HumanComment comment = curMap.get(key);
if (key.equals(uuid)) {
comment.message = newMessage;
}
@@ -173,8 +173,8 @@ public class DeleteCommentRewriter implements NoteDbRewriter {
* @param curMap the comment map of the current commit.
* @return The comments deleted by the current commit.
*/
private List<Comment> getDeletedComments(
Map<String, Comment> parMap, Map<String, Comment> curMap) {
private List<HumanComment> getDeletedComments(
Map<String, HumanComment> parMap, Map<String, HumanComment> curMap) {
return parMap.entrySet().stream()
.filter(c -> !curMap.containsKey(c.getKey()))
.map(Map.Entry::getValue)
@@ -199,22 +199,22 @@ public class DeleteCommentRewriter implements NoteDbRewriter {
RevCommit parentCommit,
ObjectInserter inserter,
ObjectReader reader,
List<Comment> putInComments,
List<Comment> deletedComments)
List<HumanComment> putInComments,
List<HumanComment> deletedComments)
throws IOException, ConfigInvalidException {
RevisionNoteMap<ChangeRevisionNote> revNotesMap =
RevisionNoteMap.parse(
noteUtil.getChangeNoteJson(),
reader,
NoteMap.read(reader, parentCommit),
Status.PUBLISHED);
HumanComment.Status.PUBLISHED);
RevisionNoteBuilder.Cache cache = new RevisionNoteBuilder.Cache(revNotesMap);
for (Comment c : putInComments) {
for (HumanComment c : putInComments) {
cache.get(c.getCommitId()).putComment(c);
}
for (Comment c : deletedComments) {
for (HumanComment c : deletedComments) {
cache.get(c.getCommitId()).deleteComment(c.key);
}

View File

@@ -26,7 +26,7 @@ import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.Project;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
@@ -50,7 +50,7 @@ public class DraftCommentNotes extends AbstractChangeNotes<DraftCommentNotes> {
private final Account.Id author;
private final Ref ref;
private ImmutableListMultimap<ObjectId, Comment> comments;
private ImmutableListMultimap<ObjectId, HumanComment> comments;
private RevisionNoteMap<ChangeRevisionNote> revisionNoteMap;
@AssistedInject
@@ -80,12 +80,12 @@ public class DraftCommentNotes extends AbstractChangeNotes<DraftCommentNotes> {
return author;
}
public ImmutableListMultimap<ObjectId, Comment> getComments() {
public ImmutableListMultimap<ObjectId, HumanComment> getComments() {
return comments;
}
public boolean containsComment(Comment c) {
for (Comment existing : comments.values()) {
public boolean containsComment(HumanComment c) {
for (HumanComment existing : comments.values()) {
if (c.key.equals(existing.key)) {
return true;
}
@@ -120,10 +120,13 @@ public class DraftCommentNotes extends AbstractChangeNotes<DraftCommentNotes> {
ObjectReader reader = handle.walk().getObjectReader();
revisionNoteMap =
RevisionNoteMap.parse(
args.changeNoteJson, reader, NoteMap.read(reader, tipCommit), Comment.Status.DRAFT);
ListMultimap<ObjectId, Comment> cs = MultimapBuilder.hashKeys().arrayListValues().build();
args.changeNoteJson,
reader,
NoteMap.read(reader, tipCommit),
HumanComment.Status.DRAFT);
ListMultimap<ObjectId, HumanComment> cs = MultimapBuilder.hashKeys().arrayListValues().build();
for (ChangeRevisionNote rn : revisionNoteMap.revisionNotes.values()) {
for (Comment c : rn.getEntities()) {
for (HumanComment c : rn.getEntities()) {
cs.put(c.getCommitId(), c);
}
}

View File

@@ -0,0 +1,28 @@
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.notedb;
import com.google.gerrit.entities.HumanComment;
import java.util.List;
/**
* Holds the raw data of a RevisionNote.
*
* <p>It is intended for deserialization from JSON only. It is used for human comments only.
*/
class HumanCommentsRevisionNoteData {
String pushCert;
List<HumanComment> comments;
}

View File

@@ -20,7 +20,8 @@ import java.util.List;
/**
* Holds the raw data of a RevisionNote.
*
* <p>It is intended for (de)serialization to JSON only.
* <p>It is intended for serialization to JSON only. It is used for human comments and robot
* comments.
*/
class RevisionNoteData {
String pushCert;

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.server.notedb;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.ObjectId;
@@ -41,7 +42,7 @@ class RevisionNoteMap<T extends RevisionNote<? extends Comment>> {
}
static RevisionNoteMap<ChangeRevisionNote> parse(
ChangeNoteJson noteJson, ObjectReader reader, NoteMap noteMap, Comment.Status status)
ChangeNoteJson noteJson, ObjectReader reader, NoteMap noteMap, HumanComment.Status status)
throws ConfigInvalidException, IOException {
ImmutableMap.Builder<ObjectId, ChangeRevisionNote> result = ImmutableMap.builder();
for (Note note : noteMap) {

View File

@@ -26,7 +26,11 @@ import java.util.List;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
/** Like {@link RevisionNote} but for robot comments. */
/**
* Holds the raw data of a RevisionNote.
*
* <p>It is intended for deserialization from JSON only. It is used for robot comments only.
*/
public class RobotCommentsRevisionNote extends RevisionNote<RobotComment> {
private final ChangeNoteJson noteUtil;

View File

@@ -24,7 +24,7 @@ import com.google.gerrit.common.data.CommentDetail;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.Patch.ChangeType;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
@@ -381,13 +381,13 @@ public class PatchScriptFactory implements Callable<PatchScript> {
}
private void loadPublished(String file) {
for (Comment c : commentsUtil.publishedByChangeFile(notes, file)) {
for (HumanComment c : commentsUtil.publishedByChangeFile(notes, file)) {
comments.include(notes.getChangeId(), c);
}
}
private void loadDrafts(Account.Id me, String file) {
for (Comment c : commentsUtil.draftByChangeFileAuthor(notes, file, me)) {
for (HumanComment c : commentsUtil.draftByChangeFileAuthor(notes, file, me)) {
comments.include(notes.getChangeId(), c);
}
}

View File

@@ -41,6 +41,7 @@ import com.google.gerrit.entities.AttentionSetUpdate;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.PatchSetApproval;
import com.google.gerrit.entities.Project;
@@ -277,7 +278,7 @@ public class ChangeData {
private List<PatchSetApproval> currentApprovals;
private List<String> currentFiles;
private Optional<DiffSummary> diffSummary;
private Collection<Comment> publishedComments;
private Collection<HumanComment> publishedComments;
private Collection<RobotComment> robotComments;
private CurrentUser visibleTo;
private List<ChangeMessage> messages;
@@ -760,12 +761,12 @@ public class ChangeData {
return reviewerUpdates;
}
public Collection<Comment> publishedComments() {
public Collection<HumanComment> publishedComments() {
if (publishedComments == null) {
if (!lazyLoad) {
return Collections.emptyList();
}
publishedComments = commentsUtil.publishedByChange(notes());
publishedComments = commentsUtil.publishedHumanCommentsByChange(notes());
}
return publishedComments;
}

View File

@@ -16,7 +16,7 @@ package com.google.gerrit.server.query.change;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.server.index.change.ChangeField;
import java.util.Objects;
@@ -39,7 +39,7 @@ public class CommentByPredicate extends ChangeIndexPredicate {
return true;
}
}
for (Comment c : cd.publishedComments()) {
for (HumanComment c : cd.publishedComments()) {
if (Objects.equals(c.author.getId(), id)) {
return true;
}

View File

@@ -22,7 +22,7 @@ import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.api.accounts.DeleteDraftCommentsInput;
@@ -48,7 +48,7 @@ import com.google.gerrit.server.query.change.ChangeQueryBuilder;
import com.google.gerrit.server.query.change.HasDraftByPredicate;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.restapi.change.CommentJson;
import com.google.gerrit.server.restapi.change.CommentJson.CommentFormatter;
import com.google.gerrit.server.restapi.change.CommentJson.HumanCommentFormatter;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdate.Factory;
import com.google.gerrit.server.update.BatchUpdateListener;
@@ -123,7 +123,8 @@ public class DeleteDraftComments
throw new AuthException("Cannot delete drafts of other user");
}
CommentFormatter commentFormatter = commentJsonProvider.get().newCommentFormatter();
HumanCommentFormatter humanCommentFormatter =
commentJsonProvider.get().newHumanCommentFormatter();
Account.Id accountId = rsrc.getUser().getAccountId();
Timestamp now = TimeUtil.nowTs();
Map<Project.NameKey, BatchUpdate> updates = new LinkedHashMap<>();
@@ -137,7 +138,7 @@ public class DeleteDraftComments
BatchUpdate update =
updates.computeIfAbsent(
cd.project(), p -> batchUpdateFactory.create(p, rsrc.getUser(), now));
Op op = new Op(commentFormatter, accountId);
Op op = new Op(humanCommentFormatter, accountId);
update.addOp(cd.getId(), op);
ops.add(op);
}
@@ -165,12 +166,12 @@ public class DeleteDraftComments
}
private class Op implements BatchUpdateOp {
private final CommentFormatter commentFormatter;
private final HumanCommentFormatter humanCommentFormatter;
private final Account.Id accountId;
private DeletedDraftCommentInfo result;
Op(CommentFormatter commentFormatter, Account.Id accountId) {
this.commentFormatter = commentFormatter;
Op(HumanCommentFormatter humanCommentFormatter, Account.Id accountId) {
this.humanCommentFormatter = humanCommentFormatter;
this.accountId = accountId;
}
@@ -179,12 +180,12 @@ public class DeleteDraftComments
throws PatchListNotAvailableException, PermissionBackendException {
ImmutableList.Builder<CommentInfo> comments = ImmutableList.builder();
boolean dirty = false;
for (Comment c : commentsUtil.draftByChangeAuthor(ctx.getNotes(), accountId)) {
for (HumanComment c : commentsUtil.draftByChangeAuthor(ctx.getNotes(), accountId)) {
dirty = true;
PatchSet.Id psId = PatchSet.id(ctx.getChange().getId(), c.key.patchSetId);
setCommentCommitId(c, patchListCache, ctx.getChange(), psUtil.get(ctx.getNotes(), psId));
commentsUtil.deleteComments(ctx.getUpdate(psId), Collections.singleton(c));
comments.add(commentFormatter.format(c));
commentsUtil.deleteHumanComments(ctx.getUpdate(psId), Collections.singleton(c));
comments.add(humanCommentFormatter.format(c));
}
if (dirty) {
result = new DeletedDraftCommentInfo();

View File

@@ -25,6 +25,7 @@ import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.FixReplacement;
import com.google.gerrit.entities.FixSuggestion;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.RobotComment;
import com.google.gerrit.extensions.client.Comment.Range;
import com.google.gerrit.extensions.client.Side;
@@ -63,8 +64,8 @@ public class CommentJson {
return this;
}
public CommentFormatter newCommentFormatter() {
return new CommentFormatter();
public HumanCommentFormatter newHumanCommentFormatter() {
return new HumanCommentFormatter();
}
public RobotCommentFormatter newRobotCommentFormatter() {
@@ -161,15 +162,15 @@ public class CommentJson {
}
}
public class CommentFormatter extends BaseCommentFormatter<Comment, CommentInfo> {
public class HumanCommentFormatter extends BaseCommentFormatter<HumanComment, CommentInfo> {
@Override
protected CommentInfo toInfo(Comment c, AccountLoader loader) {
protected CommentInfo toInfo(HumanComment c, AccountLoader loader) {
CommentInfo ci = new CommentInfo();
fillCommentInfo(c, ci, loader);
return ci;
}
private CommentFormatter() {}
private HumanCommentFormatter() {}
}
class RobotCommentFormatter extends BaseCommentFormatter<RobotComment, RobotCommentInfo> {

View File

@@ -14,28 +14,28 @@
package com.google.gerrit.server.restapi.change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.ChildCollection;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.change.CommentResource;
import com.google.gerrit.server.change.HumanCommentResource;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@Singleton
public class Comments implements ChildCollection<RevisionResource, CommentResource> {
private final DynamicMap<RestView<CommentResource>> views;
public class Comments implements ChildCollection<RevisionResource, HumanCommentResource> {
private final DynamicMap<RestView<HumanCommentResource>> views;
private final ListRevisionComments list;
private final CommentsUtil commentsUtil;
@Inject
Comments(
DynamicMap<RestView<CommentResource>> views,
DynamicMap<RestView<HumanCommentResource>> views,
ListRevisionComments list,
CommentsUtil commentsUtil) {
this.views = views;
@@ -44,7 +44,7 @@ public class Comments implements ChildCollection<RevisionResource, CommentResour
}
@Override
public DynamicMap<RestView<CommentResource>> views() {
public DynamicMap<RestView<HumanCommentResource>> views() {
return views;
}
@@ -54,13 +54,14 @@ public class Comments implements ChildCollection<RevisionResource, CommentResour
}
@Override
public CommentResource parse(RevisionResource rev, IdString id) throws ResourceNotFoundException {
public HumanCommentResource parse(RevisionResource rev, IdString id)
throws ResourceNotFoundException {
String uuid = id.get();
ChangeNotes notes = rev.getNotes();
for (Comment c : commentsUtil.publishedByPatchSet(notes, rev.getPatchSet().id())) {
for (HumanComment c : commentsUtil.publishedByPatchSet(notes, rev.getPatchSet().id())) {
if (uuid.equals(c.key.uuid)) {
return new CommentResource(rev, c);
return new HumanCommentResource(rev, c);
}
}
throw new ResourceNotFoundException(id);

View File

@@ -18,7 +18,7 @@ import static com.google.gerrit.entities.Patch.PATCHSET_LEVEL;
import static com.google.gerrit.server.CommentsUtil.setCommentCommitId;
import com.google.common.base.Strings;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.extensions.api.changes.DraftInput;
import com.google.gerrit.extensions.common.CommentInfo;
@@ -89,7 +89,7 @@ public class CreateDraftComment implements RestModifyView<RevisionResource, Draf
bu.addOp(rsrc.getChange().getId(), op);
bu.execute();
return Response.created(
commentJson.get().setFillAccounts(false).newCommentFormatter().format(op.comment));
commentJson.get().setFillAccounts(false).newHumanCommentFormatter().format(op.comment));
}
}
@@ -97,7 +97,7 @@ public class CreateDraftComment implements RestModifyView<RevisionResource, Draf
private final PatchSet.Id psId;
private final DraftInput in;
private Comment comment;
private HumanComment comment;
private Op(PatchSet.Id psId, DraftInput in) {
this.psId = psId;
@@ -115,15 +115,15 @@ public class CreateDraftComment implements RestModifyView<RevisionResource, Draf
String parentUuid = Url.decode(in.inReplyTo);
comment =
commentsUtil.newComment(
commentsUtil.newHumanComment(
ctx, in.path, ps.id(), in.side(), in.message.trim(), in.unresolved, parentUuid);
comment.setLineNbrAndRange(in.line, in.range);
comment.tag = in.tag;
setCommentCommitId(comment, patchListCache, ctx.getChange(), ps);
commentsUtil.putComments(
ctx.getUpdate(psId), Comment.Status.DRAFT, Collections.singleton(comment));
commentsUtil.putHumanComments(
ctx.getUpdate(psId), HumanComment.Status.DRAFT, Collections.singleton(comment));
return true;
}
}

View File

@@ -15,7 +15,7 @@
package com.google.gerrit.server.restapi.change;
import com.google.common.base.Strings;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.extensions.api.changes.DeleteCommentInput;
import com.google.gerrit.extensions.common.CommentInfo;
@@ -26,7 +26,7 @@ import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.change.CommentResource;
import com.google.gerrit.server.change.HumanCommentResource;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
@@ -45,7 +45,7 @@ import java.util.Optional;
import org.eclipse.jgit.errors.ConfigInvalidException;
@Singleton
public class DeleteComment implements RestModifyView<CommentResource, DeleteCommentInput> {
public class DeleteComment implements RestModifyView<HumanCommentResource, DeleteCommentInput> {
private final Provider<CurrentUser> userProvider;
private final PermissionBackend permissionBackend;
@@ -71,7 +71,7 @@ public class DeleteComment implements RestModifyView<CommentResource, DeleteComm
}
@Override
public Response<CommentInfo> apply(CommentResource rsrc, DeleteCommentInput input)
public Response<CommentInfo> apply(HumanCommentResource rsrc, DeleteCommentInput input)
throws RestApiException, IOException, ConfigInvalidException, PermissionBackendException,
UpdateException {
CurrentUser user = userProvider.get();
@@ -90,15 +90,15 @@ public class DeleteComment implements RestModifyView<CommentResource, DeleteComm
ChangeNotes updatedNotes =
notesFactory.createChecked(rsrc.getRevisionResource().getChange().getId());
List<Comment> changeComments = commentsUtil.publishedByChange(updatedNotes);
Optional<Comment> updatedComment =
List<HumanComment> changeComments = commentsUtil.publishedHumanCommentsByChange(updatedNotes);
Optional<HumanComment> updatedComment =
changeComments.stream().filter(c -> c.key.equals(rsrc.getComment().key)).findFirst();
if (!updatedComment.isPresent()) {
// This should not happen as this endpoint should not remove the whole comment.
throw new ResourceNotFoundException("comment not found: " + rsrc.getComment().key);
}
return Response.ok(commentJson.get().newCommentFormatter().format(updatedComment.get()));
return Response.ok(commentJson.get().newHumanCommentFormatter().format(updatedComment.get()));
}
private static String getCommentNewMessage(String name, String reason) {
@@ -110,10 +110,10 @@ public class DeleteComment implements RestModifyView<CommentResource, DeleteComm
}
private class DeleteCommentOp implements BatchUpdateOp {
private final CommentResource rsrc;
private final HumanCommentResource rsrc;
private final String newMessage;
DeleteCommentOp(CommentResource rsrc, String newMessage) {
DeleteCommentOp(HumanCommentResource rsrc, String newMessage) {
this.rsrc = rsrc;
this.newMessage = newMessage;
}

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server.restapi.change;
import static com.google.gerrit.server.CommentsUtil.setCommentCommitId;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.Input;
@@ -80,7 +81,7 @@ public class DeleteDraftComment implements RestModifyView<DraftCommentResource,
@Override
public boolean updateChange(ChangeContext ctx)
throws ResourceNotFoundException, PatchListNotAvailableException {
Optional<Comment> maybeComment =
Optional<HumanComment> maybeComment =
commentsUtil.getDraft(ctx.getNotes(), ctx.getIdentifiedUser(), key);
if (!maybeComment.isPresent()) {
return false; // Nothing to do.
@@ -90,9 +91,9 @@ public class DeleteDraftComment implements RestModifyView<DraftCommentResource,
if (ps == null) {
throw new ResourceNotFoundException("patch set not found: " + psId);
}
Comment c = maybeComment.get();
HumanComment c = maybeComment.get();
setCommentCommitId(c, patchListCache, ctx.getChange(), ps);
commentsUtil.deleteComments(ctx.getUpdate(psId), Collections.singleton(c));
commentsUtil.deleteHumanComments(ctx.getUpdate(psId), Collections.singleton(c));
return true;
}
}

View File

@@ -14,7 +14,7 @@
package com.google.gerrit.server.restapi.change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ChildCollection;
@@ -64,7 +64,7 @@ public class DraftComments implements ChildCollection<RevisionResource, DraftCom
throws ResourceNotFoundException, AuthException {
checkIdentifiedUser();
String uuid = id.get();
for (Comment c :
for (HumanComment c :
commentsUtil.draftByPatchSetAuthor(
rev.getPatchSet().id(), rev.getAccountId(), rev.getNotes())) {
if (uuid.equals(c.key.uuid)) {

View File

@@ -17,14 +17,14 @@ package com.google.gerrit.server.restapi.change;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.server.change.CommentResource;
import com.google.gerrit.server.change.HumanCommentResource;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@Singleton
public class GetComment implements RestReadView<CommentResource> {
public class GetComment implements RestReadView<HumanCommentResource> {
private final Provider<CommentJson> commentJson;
@@ -34,7 +34,7 @@ public class GetComment implements RestReadView<CommentResource> {
}
@Override
public Response<CommentInfo> apply(CommentResource rsrc) throws PermissionBackendException {
return Response.ok(commentJson.get().newCommentFormatter().format(rsrc.getComment()));
public Response<CommentInfo> apply(HumanCommentResource rsrc) throws PermissionBackendException {
return Response.ok(commentJson.get().newHumanCommentFormatter().format(rsrc.getComment()));
}
}

View File

@@ -35,6 +35,6 @@ public class GetDraftComment implements RestReadView<DraftCommentResource> {
@Override
public Response<CommentInfo> apply(DraftCommentResource rsrc) throws PermissionBackendException {
return Response.ok(commentJson.get().newCommentFormatter().format(rsrc.getComment()));
return Response.ok(commentJson.get().newHumanCommentFormatter().format(rsrc.getComment()));
}
}

View File

@@ -18,7 +18,7 @@ import static java.util.stream.Collectors.toList;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.Response;
@@ -28,7 +28,6 @@ import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.restapi.change.CommentJson.CommentFormatter;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@@ -64,12 +63,12 @@ public class ListChangeComments implements RestReadView<ChangeResource> {
return getAsList(listComments(rsrc), rsrc);
}
private Iterable<Comment> listComments(ChangeResource rsrc) {
private Iterable<HumanComment> listComments(ChangeResource rsrc) {
ChangeData cd = changeDataFactory.create(rsrc.getNotes());
return commentsUtil.publishedByChange(cd.notes());
return commentsUtil.publishedHumanCommentsByChange(cd.notes());
}
private ImmutableList<CommentInfo> getAsList(Iterable<Comment> comments, ChangeResource rsrc)
private ImmutableList<CommentInfo> getAsList(Iterable<HumanComment> comments, ChangeResource rsrc)
throws PermissionBackendException {
ImmutableList<CommentInfo> commentInfos = getCommentFormatter().formatAsList(comments);
List<ChangeMessage> changeMessages = changeMessagesUtil.byChange(rsrc.getNotes());
@@ -77,8 +76,8 @@ public class ListChangeComments implements RestReadView<ChangeResource> {
return commentInfos;
}
private Map<String, List<CommentInfo>> getAsMap(Iterable<Comment> comments, ChangeResource rsrc)
throws PermissionBackendException {
private Map<String, List<CommentInfo>> getAsMap(
Iterable<HumanComment> comments, ChangeResource rsrc) throws PermissionBackendException {
Map<String, List<CommentInfo>> commentInfosMap = getCommentFormatter().format(comments);
List<CommentInfo> commentInfos =
commentInfosMap.values().stream().flatMap(List::stream).collect(toList());
@@ -87,7 +86,7 @@ public class ListChangeComments implements RestReadView<ChangeResource> {
return commentInfosMap;
}
private CommentFormatter getCommentFormatter() {
return commentJson.get().setFillAccounts(true).setFillPatchSet(true).newCommentFormatter();
private CommentJson.HumanCommentFormatter getCommentFormatter() {
return commentJson.get().setFillAccounts(true).setFillPatchSet(true).newHumanCommentFormatter();
}
}

View File

@@ -14,7 +14,7 @@
package com.google.gerrit.server.restapi.change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.Response;
@@ -23,7 +23,7 @@ import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.restapi.change.CommentJson.CommentFormatter;
import com.google.gerrit.server.restapi.change.CommentJson.HumanCommentFormatter;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@@ -46,7 +46,7 @@ public class ListChangeDrafts implements RestReadView<ChangeResource> {
this.commentsUtil = commentsUtil;
}
private Iterable<Comment> listComments(ChangeResource rsrc) {
private Iterable<HumanComment> listComments(ChangeResource rsrc) {
ChangeData cd = changeDataFactory.create(rsrc.getNotes());
return commentsUtil.draftByChangeAuthor(cd.notes(), rsrc.getUser().getAccountId());
}
@@ -68,7 +68,11 @@ public class ListChangeDrafts implements RestReadView<ChangeResource> {
return getCommentFormatter().formatAsList(listComments(rsrc));
}
private CommentFormatter getCommentFormatter() {
return commentJson.get().setFillAccounts(false).setFillPatchSet(true).newCommentFormatter();
private HumanCommentFormatter getCommentFormatter() {
return commentJson
.get()
.setFillAccounts(false)
.setFillPatchSet(true)
.newHumanCommentFormatter();
}
}

View File

@@ -14,7 +14,7 @@
package com.google.gerrit.server.restapi.change;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.notedb.ChangeNotes;
@@ -35,7 +35,7 @@ public class ListRevisionComments extends ListRevisionDrafts {
}
@Override
protected Iterable<Comment> listComments(RevisionResource rsrc) {
protected Iterable<HumanComment> listComments(RevisionResource rsrc) {
ChangeNotes notes = rsrc.getNotes();
return commentsUtil.publishedByPatchSet(notes, rsrc.getPatchSet().id());
}

View File

@@ -15,7 +15,7 @@
package com.google.gerrit.server.restapi.change;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestReadView;
@@ -39,7 +39,7 @@ public class ListRevisionDrafts implements RestReadView<RevisionResource> {
this.commentsUtil = commentsUtil;
}
protected Iterable<Comment> listComments(RevisionResource rsrc) {
protected Iterable<HumanComment> listComments(RevisionResource rsrc) {
return commentsUtil.draftByPatchSetAuthor(
rsrc.getPatchSet().id(), rsrc.getAccountId(), rsrc.getNotes());
}
@@ -55,7 +55,7 @@ public class ListRevisionDrafts implements RestReadView<RevisionResource> {
commentJson
.get()
.setFillAccounts(includeAuthorInfo())
.newCommentFormatter()
.newHumanCommentFormatter()
.format(listComments(rsrc)));
}
@@ -64,7 +64,7 @@ public class ListRevisionDrafts implements RestReadView<RevisionResource> {
return commentJson
.get()
.setFillAccounts(includeAuthorInfo())
.newCommentFormatter()
.newHumanCommentFormatter()
.formatAsList(listComments(rsrc));
}
}

View File

@@ -18,10 +18,10 @@ import static com.google.gerrit.server.change.AttentionSetEntryResource.ATTENTIO
import static com.google.gerrit.server.change.ChangeEditResource.CHANGE_EDIT_KIND;
import static com.google.gerrit.server.change.ChangeMessageResource.CHANGE_MESSAGE_KIND;
import static com.google.gerrit.server.change.ChangeResource.CHANGE_KIND;
import static com.google.gerrit.server.change.CommentResource.COMMENT_KIND;
import static com.google.gerrit.server.change.DraftCommentResource.DRAFT_COMMENT_KIND;
import static com.google.gerrit.server.change.FileResource.FILE_KIND;
import static com.google.gerrit.server.change.FixResource.FIX_KIND;
import static com.google.gerrit.server.change.HumanCommentResource.COMMENT_KIND;
import static com.google.gerrit.server.change.ReviewerResource.REVIEWER_KIND;
import static com.google.gerrit.server.change.RevisionResource.REVISION_KIND;
import static com.google.gerrit.server.change.RobotCommentResource.ROBOT_COMMENT_KIND;

View File

@@ -49,6 +49,7 @@ import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.FixReplacement;
import com.google.gerrit.entities.FixSuggestion;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.PatchSetApproval;
@@ -811,8 +812,8 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
}
/**
* Used to compare existing {@link Comment}-s with {@link CommentInput} comments by copying only
* the fields to compare.
* Used to compare existing {@link HumanComment}-s with {@link CommentInput} comments by copying
* only the fields to compare.
*/
@AutoValue
abstract static class CommentSetEntry {
@@ -942,7 +943,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
// HashMap instead of Collections.emptyMap() avoids warning about remove() on immutable
// object.
Map<String, Comment> drafts = new HashMap<>();
Map<String, HumanComment> drafts = new HashMap<>();
// If there are inputComments we need the deduplication loop below, so we have to read (and
// publish) drafts here.
if (!inputComments.isEmpty() || in.drafts != DraftHandling.KEEP) {
@@ -954,7 +955,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
}
// This will be populated with Comment-s created from inputComments.
List<Comment> toPublish = new ArrayList<>();
List<HumanComment> toPublish = new ArrayList<>();
Set<CommentSetEntry> existingComments =
in.omitDuplicateComments ? readExistingComments(ctx) : Collections.emptySet();
@@ -965,11 +966,11 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
for (Map.Entry<String, List<CommentInput>> entry : inputComments.entrySet()) {
String path = entry.getKey();
for (CommentInput inputComment : entry.getValue()) {
Comment comment = drafts.remove(Url.decode(inputComment.id));
HumanComment comment = drafts.remove(Url.decode(inputComment.id));
if (comment == null) {
String parent = Url.decode(inputComment.inReplyTo);
comment =
commentsUtil.newComment(
commentsUtil.newHumanComment(
ctx,
path,
psId,
@@ -1014,7 +1015,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
break;
}
ChangeUpdate changeUpdate = ctx.getUpdate(psId);
commentsUtil.putComments(changeUpdate, Comment.Status.PUBLISHED, toPublish);
commentsUtil.putHumanComments(changeUpdate, HumanComment.Status.PUBLISHED, toPublish);
comments.addAll(toPublish);
return !toPublish.isEmpty();
}
@@ -1134,7 +1135,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
}
private Set<CommentSetEntry> readExistingComments(ChangeContext ctx) {
return commentsUtil.publishedByChange(ctx.getNotes()).stream()
return commentsUtil.publishedHumanCommentsByChange(ctx.getNotes()).stream()
.map(CommentSetEntry::create)
.collect(toSet());
}
@@ -1145,7 +1146,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
.collect(toSet());
}
private Map<String, Comment> changeDrafts(ChangeContext ctx) {
private Map<String, HumanComment> changeDrafts(ChangeContext ctx) {
return commentsUtil.draftByChangeAuthor(ctx.getNotes(), user.getAccountId()).stream()
.collect(
Collectors.toMap(
@@ -1156,7 +1157,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
}));
}
private Map<String, Comment> patchSetDrafts(ChangeContext ctx) {
private Map<String, HumanComment> patchSetDrafts(ChangeContext ctx) {
return commentsUtil.draftByPatchSetAuthor(psId, user.getAccountId(), ctx.getNotes()).stream()
.collect(Collectors.toMap(c -> c.key.uuid, c -> c));
}

View File

@@ -18,6 +18,7 @@ import static com.google.gerrit.entities.Patch.PATCHSET_LEVEL;
import static com.google.gerrit.server.CommentsUtil.setCommentCommitId;
import com.google.gerrit.entities.Comment;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.extensions.api.changes.DraftInput;
import com.google.gerrit.extensions.common.CommentInfo;
@@ -93,7 +94,7 @@ public class PutDraftComment implements RestModifyView<DraftCommentResource, Dra
bu.addOp(rsrc.getChange().getId(), op);
bu.execute();
return Response.ok(
commentJson.get().setFillAccounts(false).newCommentFormatter().format(op.comment));
commentJson.get().setFillAccounts(false).newHumanCommentFormatter().format(op.comment));
}
}
@@ -101,7 +102,7 @@ public class PutDraftComment implements RestModifyView<DraftCommentResource, Dra
private final Comment.Key key;
private final DraftInput in;
private Comment comment;
private HumanComment comment;
private Op(Comment.Key key, DraftInput in) {
this.key = key;
@@ -111,15 +112,15 @@ public class PutDraftComment implements RestModifyView<DraftCommentResource, Dra
@Override
public boolean updateChange(ChangeContext ctx)
throws ResourceNotFoundException, PatchListNotAvailableException {
Optional<Comment> maybeComment =
Optional<HumanComment> maybeComment =
commentsUtil.getDraft(ctx.getNotes(), ctx.getIdentifiedUser(), key);
if (!maybeComment.isPresent()) {
// Disappeared out from under us. Can't easily fall back to insert,
// because the input might be missing required fields. Just give up.
throw new ResourceNotFoundException("comment not found: " + key);
}
Comment origComment = maybeComment.get();
comment = new Comment(origComment);
HumanComment origComment = maybeComment.get();
comment = new HumanComment(origComment);
// Copy constructor preserved old real author; replace with current real
// user.
ctx.getUser().updateRealAccountId(comment::setRealAuthor);
@@ -135,17 +136,19 @@ public class PutDraftComment implements RestModifyView<DraftCommentResource, Dra
// Updating the path alters the primary key, which isn't possible.
// Delete then recreate the comment instead of an update.
commentsUtil.deleteComments(update, Collections.singleton(origComment));
commentsUtil.deleteHumanComments(update, Collections.singleton(origComment));
comment.key.filename = in.path;
}
setCommentCommitId(comment, patchListCache, ctx.getChange(), ps);
commentsUtil.putComments(
update, Comment.Status.DRAFT, Collections.singleton(update(comment, in, ctx.getWhen())));
commentsUtil.putHumanComments(
update,
HumanComment.Status.DRAFT,
Collections.singleton(update(comment, in, ctx.getWhen())));
return true;
}
}
private static Comment update(Comment e, DraftInput in, Timestamp when) {
private static HumanComment update(HumanComment e, DraftInput in, Timestamp when) {
if (in.side != null) {
e.side = in.side();
}