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.extensions.client; 16 : 17 : import java.sql.Timestamp; 18 : import java.time.Instant; 19 : import java.util.Comparator; 20 : import java.util.Objects; 21 : 22 30 : public abstract class Comment { 23 : /** 24 : * Patch set number containing this commit. 25 : * 26 : * <p>Only set in contexts where comments may come from multiple patch sets. 27 : */ 28 : public Integer patchSet; 29 : 30 : public String id; 31 : public String path; 32 : public Side side; 33 : public Integer parent; 34 : /** Value 0 or null indicates a file comment, normal lines start at 1. */ 35 : public Integer line; 36 : 37 : public Range range; 38 : public String inReplyTo; 39 : 40 : // TODO(issue-15508): Migrate timestamp fields in *Info/*Input classes from type Timestamp to 41 : // Instant 42 : public Timestamp updated; 43 : 44 : public String message; 45 : 46 : /** 47 : * Hex commit SHA1 (as 40 characters hex string) of the commit of the patchset to which this 48 : * comment applies. 49 : */ 50 : public String commitId; 51 : 52 : // TODO(issue-15508): Migrate timestamp fields in *Info/*Input classes from type Timestamp to 53 : // Instant 54 : @SuppressWarnings("JdkObsolete") 55 : public Instant getUpdated() { 56 14 : return updated.toInstant(); 57 : } 58 : 59 : // TODO(issue-15508): Migrate timestamp fields in *Info/*Input classes from type Timestamp to 60 : // Instant 61 : @SuppressWarnings("JdkObsolete") 62 : public void setUpdated(Instant when) { 63 2 : updated = Timestamp.from(when); 64 2 : } 65 : 66 15 : public static class Range implements Comparable<Range> { 67 15 : private static final Comparator<Range> RANGE_COMPARATOR = 68 15 : Comparator.<Range>comparingInt(range -> range.startLine) 69 15 : .thenComparingInt(range -> range.startCharacter) 70 15 : .thenComparingInt(range -> range.endLine) 71 15 : .thenComparingInt(range -> range.endCharacter); 72 : 73 : // Start position is inclusive; end position is exclusive. 74 : public int startLine; // 1-based 75 : public int startCharacter; // 0-based 76 : public int endLine; // 1-based 77 : public int endCharacter; // 0-based 78 : 79 : public boolean isValid() { 80 8 : return startLine > 0 81 : && startCharacter >= 0 82 : && endLine > 0 83 : && endCharacter >= 0 84 : && startLine <= endLine 85 : && (startLine != endLine || startCharacter <= endCharacter); 86 : } 87 : 88 : @Override 89 : public boolean equals(Object o) { 90 2 : if (o instanceof Range) { 91 2 : Range r = (Range) o; 92 2 : return startLine == r.startLine 93 : && startCharacter == r.startCharacter 94 : && endLine == r.endLine 95 : && endCharacter == r.endCharacter; 96 : } 97 0 : return false; 98 : } 99 : 100 : @Override 101 : public int hashCode() { 102 1 : return Objects.hash(startLine, startCharacter, endLine, endCharacter); 103 : } 104 : 105 : @Override 106 : public String toString() { 107 0 : return "Range{" 108 : + "startLine=" 109 : + startLine 110 : + ", startCharacter=" 111 : + startCharacter 112 : + ", endLine=" 113 : + endLine 114 : + ", endCharacter=" 115 : + endCharacter 116 : + '}'; 117 : } 118 : 119 : @Override 120 : public int compareTo(Range otherRange) { 121 1 : return RANGE_COMPARATOR.compare(this, otherRange); 122 : } 123 : } 124 : 125 : public short side() { 126 26 : if (side == Side.PARENT) { 127 1 : return (short) (parent == null ? 0 : -parent.shortValue()); 128 : } 129 26 : return 1; 130 : } 131 : 132 : // This is a value class that allows adding attributes by subclassing. 133 : // Doing this is discouraged and using composition rather than inheritance to add fields to value 134 : // types is preferred. However this class is part of the extension API, hence we cannot change it 135 : // without breaking the API. Hence suppress the EqualsGetClass warning here. 136 : @SuppressWarnings("EqualsGetClass") 137 : @Override 138 : public boolean equals(Object o) { 139 4 : if (this == o) { 140 0 : return true; 141 : } 142 4 : if (o != null && getClass() == o.getClass()) { 143 4 : Comment c = (Comment) o; 144 4 : return Objects.equals(patchSet, c.patchSet) 145 4 : && Objects.equals(id, c.id) 146 3 : && Objects.equals(path, c.path) 147 3 : && Objects.equals(side, c.side) 148 3 : && Objects.equals(parent, c.parent) 149 3 : && Objects.equals(line, c.line) 150 3 : && Objects.equals(range, c.range) 151 3 : && Objects.equals(inReplyTo, c.inReplyTo) 152 3 : && Objects.equals(updated, c.updated) 153 3 : && Objects.equals(message, c.message) 154 4 : && Objects.equals(commitId, c.commitId); 155 : } 156 0 : return false; 157 : } 158 : 159 : @Override 160 : public int hashCode() { 161 3 : return Objects.hash(patchSet, id, path, side, parent, line, range, inReplyTo, updated, message); 162 : } 163 : }