Line data Source code
1 : // Copyright (C) 2014 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.notedb; 16 : 17 : import static com.google.common.base.Preconditions.checkArgument; 18 : import static com.google.gerrit.entities.RefNames.refsDraftComments; 19 : import static java.util.Objects.requireNonNull; 20 : 21 : import com.google.common.annotations.VisibleForTesting; 22 : import com.google.common.collect.ImmutableListMultimap; 23 : import com.google.common.flogger.FluentLogger; 24 : import com.google.gerrit.common.Nullable; 25 : import com.google.gerrit.entities.Account; 26 : import com.google.gerrit.entities.Change; 27 : import com.google.gerrit.entities.HumanComment; 28 : import com.google.gerrit.entities.Project; 29 : import com.google.inject.assistedinject.Assisted; 30 : import com.google.inject.assistedinject.AssistedInject; 31 : import java.io.IOException; 32 : import org.eclipse.jgit.errors.ConfigInvalidException; 33 : import org.eclipse.jgit.lib.ObjectId; 34 : import org.eclipse.jgit.lib.ObjectReader; 35 : import org.eclipse.jgit.lib.Ref; 36 : import org.eclipse.jgit.lib.Repository; 37 : import org.eclipse.jgit.notes.NoteMap; 38 : import org.eclipse.jgit.revwalk.RevCommit; 39 : 40 : /** View of the draft comments for a single {@link Change} based on the log of its drafts branch. */ 41 : public class DraftCommentNotes extends AbstractChangeNotes<DraftCommentNotes> { 42 29 : private static final FluentLogger logger = FluentLogger.forEnclosingClass(); 43 : 44 : public interface Factory { 45 : DraftCommentNotes create(Change.Id changeId, Account.Id accountId); 46 : } 47 : 48 : private final Account.Id author; 49 : private final Ref ref; 50 : 51 : private ImmutableListMultimap<ObjectId, HumanComment> comments; 52 : private RevisionNoteMap<ChangeRevisionNote> revisionNoteMap; 53 : 54 : @AssistedInject 55 : DraftCommentNotes(Args args, @Assisted Change.Id changeId, @Assisted Account.Id author) { 56 2 : this(args, changeId, author, null); 57 2 : } 58 : 59 : DraftCommentNotes(Args args, Change.Id changeId, Account.Id author, @Nullable Ref ref) { 60 29 : super(args, changeId, null); 61 29 : this.author = requireNonNull(author); 62 29 : this.ref = ref; 63 29 : if (ref != null) { 64 0 : checkArgument( 65 0 : ref.getName().equals(getRefName()), 66 : "draft ref not for change %s and account %s: %s", 67 0 : getChangeId(), 68 : author, 69 0 : ref.getName()); 70 : } 71 29 : } 72 : 73 : RevisionNoteMap<ChangeRevisionNote> getRevisionNoteMap() { 74 9 : return revisionNoteMap; 75 : } 76 : 77 : public Account.Id getAuthor() { 78 1 : return author; 79 : } 80 : 81 : public ImmutableListMultimap<ObjectId, HumanComment> getComments() { 82 29 : return comments; 83 : } 84 : 85 : public boolean containsComment(HumanComment c) { 86 0 : for (HumanComment existing : comments.values()) { 87 0 : if (c.key.equals(existing.key)) { 88 0 : return true; 89 : } 90 0 : } 91 0 : return false; 92 : } 93 : 94 : @Override 95 : protected String getRefName() { 96 29 : return refsDraftComments(getChangeId(), author); 97 : } 98 : 99 : @Override 100 : protected ObjectId readRef(Repository repo) throws IOException { 101 29 : if (ref != null) { 102 0 : return ref.getObjectId(); 103 : } 104 29 : return super.readRef(repo); 105 : } 106 : 107 : @Override 108 : protected void onLoad(LoadHandle handle) throws IOException, ConfigInvalidException { 109 29 : ObjectId rev = handle.id(); 110 29 : if (rev == null) { 111 24 : loadDefaults(); 112 24 : return; 113 : } 114 : 115 21 : logger.atFine().log( 116 21 : "Load draft comment notes for change %s of project %s", getChangeId(), getProjectName()); 117 21 : RevCommit tipCommit = handle.walk().parseCommit(rev); 118 21 : ObjectReader reader = handle.walk().getObjectReader(); 119 21 : revisionNoteMap = 120 21 : RevisionNoteMap.parse( 121 : args.changeNoteJson, 122 : reader, 123 21 : NoteMap.read(reader, tipCommit), 124 : HumanComment.Status.DRAFT); 125 21 : ImmutableListMultimap.Builder<ObjectId, HumanComment> cs = ImmutableListMultimap.builder(); 126 21 : for (ChangeRevisionNote rn : revisionNoteMap.revisionNotes.values()) { 127 21 : for (HumanComment c : rn.getEntities()) { 128 21 : cs.put(c.getCommitId(), c); 129 21 : } 130 21 : } 131 21 : comments = cs.build(); 132 21 : } 133 : 134 : @Override 135 : protected void loadDefaults() { 136 24 : comments = ImmutableListMultimap.of(); 137 24 : } 138 : 139 : @Override 140 : public Project.NameKey getProjectName() { 141 29 : return args.allUsers; 142 : } 143 : 144 : @Nullable 145 : @VisibleForTesting 146 : NoteMap getNoteMap() { 147 1 : return revisionNoteMap != null ? revisionNoteMap.noteMap : null; 148 : } 149 : }