Line data Source code
1 : // Copyright (C) 2020 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.change; 16 : 17 : import com.google.auto.value.AutoValue; 18 : import com.google.common.base.Preconditions; 19 : import com.google.common.collect.ImmutableList; 20 : import com.google.common.collect.Streams; 21 : import com.google.gerrit.entities.Comment; 22 : import com.google.gerrit.entities.HumanComment; 23 : import java.util.List; 24 : import java.util.Optional; 25 : 26 : /** 27 : * Representation of a comment thread. 28 : * 29 : * <p>A comment thread consists of at least one comment. 30 : * 31 : * @param <T> type of comments in the thread. Can also be {@link Comment} if the thread mixes 32 : * comments of different types. 33 : */ 34 : @AutoValue 35 26 : public abstract class CommentThread<T extends Comment> { 36 : 37 : /** Comments in the thread in exactly the order they appear in the thread. */ 38 : public abstract ImmutableList<T> comments(); 39 : 40 : /** Whether the whole thread is considered as unresolved. */ 41 : public boolean unresolved() { 42 26 : Optional<HumanComment> lastHumanComment = 43 26 : Streams.findLast( 44 26 : comments().stream() 45 26 : .filter(HumanComment.class::isInstance) 46 26 : .map(HumanComment.class::cast)); 47 : // We often use false == null for boolean fields. It's also a safe fall-back if no human comment 48 : // is part of the thread. 49 26 : return lastHumanComment.map(comment -> comment.unresolved).orElse(false); 50 : } 51 : 52 : public static <T extends Comment> Builder<T> builder() { 53 26 : return new AutoValue_CommentThread.Builder<>(); 54 : } 55 : 56 : @AutoValue.Builder 57 26 : public abstract static class Builder<T extends Comment> { 58 : 59 : public abstract Builder<T> comments(List<T> value); 60 : 61 : public Builder<T> addComment(T comment) { 62 26 : commentsBuilder().add(comment); 63 26 : return this; 64 : } 65 : 66 : abstract ImmutableList.Builder<T> commentsBuilder(); 67 : 68 : abstract ImmutableList<T> comments(); 69 : 70 : abstract CommentThread<T> autoBuild(); 71 : 72 : public CommentThread<T> build() { 73 26 : Preconditions.checkState( 74 26 : !comments().isEmpty(), "A comment thread must contain at least one comment."); 75 26 : return autoBuild(); 76 : } 77 : } 78 : }