summaryrefslogtreecommitdiffstats
path: root/gerrit-common/src/main/java/com/google/gerrit/common/data/CommentDetail.java
diff options
context:
space:
mode:
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.java195
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;
+ }
+}