diff options
Diffstat (limited to 'gerrit-common/src/main/java/com/google/gerrit/common/data/CommentDetail.java')
-rw-r--r-- | gerrit-common/src/main/java/com/google/gerrit/common/data/CommentDetail.java | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/CommentDetail.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/CommentDetail.java new file mode 100644 index 0000000000..e35fb78c5f --- /dev/null +++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/CommentDetail.java @@ -0,0 +1,195 @@ +// Copyright (C) 2009 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.common.data; + +import com.google.gerrit.reviewdb.Patch; +import com.google.gerrit.reviewdb.PatchLineComment; +import com.google.gerrit.reviewdb.PatchSet; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CommentDetail { + protected List<PatchLineComment> commentsA; + protected List<PatchLineComment> commentsB; + protected List<Patch> history; + protected AccountInfoCache accounts; + + private transient PatchSet.Id idA; + private transient PatchSet.Id idB; + private transient Map<Integer, List<PatchLineComment>> forA; + private transient Map<Integer, List<PatchLineComment>> forB; + + public CommentDetail(final PatchSet.Id a, final PatchSet.Id b) { + commentsA = new ArrayList<PatchLineComment>(); + commentsB = new ArrayList<PatchLineComment>(); + + idA = a; + idB = b; + } + + protected CommentDetail() { + } + + public boolean include(final PatchLineComment p) { + final PatchSet.Id psId = p.getKey().getParentKey().getParentKey(); + switch (p.getSide()) { + case 0: + if (idA == null && idB.equals(psId)) { + commentsA.add(p); + return true; + } + break; + + case 1: + if (idA != null && idA.equals(psId)) { + commentsA.add(p); + return true; + } + + if (idB.equals(psId)) { + commentsB.add(p); + return true; + } + break; + } + return false; + } + + public void setAccountInfoCache(final AccountInfoCache a) { + accounts = a; + } + + public void setHistory(final List<Patch> h) { + history = h; + } + + public AccountInfoCache getAccounts() { + return accounts; + } + + public List<Patch> getHistory() { + return history; + } + + public List<PatchLineComment> getCommentsA() { + return commentsA; + } + + public List<PatchLineComment> getCommentsB() { + return commentsB; + } + + public boolean isEmpty() { + return commentsA.isEmpty() && commentsB.isEmpty(); + } + + public List<PatchLineComment> getForA(final int lineNbr) { + if (lineNbr == 0) { + return Collections.emptyList(); + } + if (forA == null) { + forA = index(commentsA); + } + return get(forA, lineNbr); + } + + public List<PatchLineComment> getForB(final int lineNbr) { + if (lineNbr == 0) { + return Collections.emptyList(); + } + if (forB == null) { + forB = index(commentsB); + } + return get(forB, lineNbr); + } + + private static List<PatchLineComment> get( + final Map<Integer, List<PatchLineComment>> m, final int i) { + final List<PatchLineComment> r = m.get(i); + return r != null ? orderComments(r) : Collections.<PatchLineComment> emptyList(); + } + + /** + * Order the comments based on their parent_uuid parent. It is possible to do this by + * iterating over the list only once but it's probably overkill since the number of comments + * on a given line will be small most of the time. + * + * @param comments The list of comments for a given line. + * @return The comments sorted as they should appear in the UI + */ + private static List<PatchLineComment> orderComments(List<PatchLineComment> comments) { + // Map of comments keyed by their parent. The values are lists of comments since it is + // possible for several comments to have the same parent (this can happen if two reviewers + // click Reply on the same comment at the same time). Such comments will be displayed under + // their correct parent in chronological order. + Map<String, List<PatchLineComment>> parentMap = new HashMap<String, List<PatchLineComment>>(); + + // It's possible to have more than one root comment if two reviewers create a comment on the + // same line at the same time + List<PatchLineComment> rootComments = new ArrayList<PatchLineComment>(); + + // Store all the comments in parentMap, keyed by their parent + for (PatchLineComment c : comments) { + String parentUuid = c.getParentUuid(); + List<PatchLineComment> l = parentMap.get(parentUuid); + if (l == null) { + l = new ArrayList<PatchLineComment>(); + parentMap.put(parentUuid, l); + } + l.add(c); + if (parentUuid == null) rootComments.add(c); + } + + // Add the comments in the list, starting with the head and then going through all the + // comments that have it as a parent, and so on + List<PatchLineComment> result = new ArrayList<PatchLineComment>(); + addChildren(parentMap, rootComments, result); + + return result; + } + + /** + * Add the comments to <code>outResult</code>, depth first + */ + private static void addChildren(Map<String, List<PatchLineComment>> parentMap, + List<PatchLineComment> children, List<PatchLineComment> outResult) { + if (children != null) { + for (PatchLineComment c : children) { + outResult.add(c); + addChildren(parentMap, parentMap.get(c.getKey().get()), outResult); + } + } + } + + private Map<Integer, List<PatchLineComment>> index( + final List<PatchLineComment> in) { + final HashMap<Integer, List<PatchLineComment>> r; + + r = new HashMap<Integer, List<PatchLineComment>>(); + for (final PatchLineComment p : in) { + List<PatchLineComment> l = r.get(p.getLine()); + if (l == null) { + l = new ArrayList<PatchLineComment>(); + r.put(p.getLine(), l); + } + l.add(p); + } + return r; + } +} |