Line data Source code
1 : // Copyright (C) 2009 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.patch;
16 :
17 : import static com.google.common.base.Preconditions.checkState;
18 : import static org.eclipse.jgit.lib.ObjectIdSerializer.read;
19 : import static org.eclipse.jgit.lib.ObjectIdSerializer.readWithoutMarker;
20 : import static org.eclipse.jgit.lib.ObjectIdSerializer.write;
21 : import static org.eclipse.jgit.lib.ObjectIdSerializer.writeWithoutMarker;
22 :
23 : import com.google.common.collect.ImmutableBiMap;
24 : import com.google.gerrit.common.Nullable;
25 : import com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace;
26 : import com.google.gerrit.git.ObjectIds;
27 : import java.io.IOException;
28 : import java.io.ObjectInputStream;
29 : import java.io.ObjectOutputStream;
30 : import java.io.Serializable;
31 : import java.util.Objects;
32 : import org.eclipse.jgit.lib.AnyObjectId;
33 : import org.eclipse.jgit.lib.ObjectId;
34 :
35 : public class PatchListKey implements Serializable {
36 : public static final long serialVersionUID = 32L;
37 :
38 103 : public static final ImmutableBiMap<Whitespace, Character> WHITESPACE_TYPES =
39 103 : ImmutableBiMap.of(
40 103 : Whitespace.IGNORE_NONE, 'N',
41 103 : Whitespace.IGNORE_TRAILING, 'E',
42 103 : Whitespace.IGNORE_LEADING_AND_TRAILING, 'S',
43 103 : Whitespace.IGNORE_ALL, 'A');
44 :
45 : static {
46 103 : checkState(WHITESPACE_TYPES.size() == Whitespace.values().length);
47 103 : }
48 :
49 : public static PatchListKey againstDefaultBase(AnyObjectId newId, Whitespace ws) {
50 103 : return new PatchListKey(null, newId, ws);
51 : }
52 :
53 : public static PatchListKey againstParentNum(int parentNum, AnyObjectId newId, Whitespace ws) {
54 30 : return new PatchListKey(parentNum, newId, ws);
55 : }
56 :
57 : public static PatchListKey againstCommit(
58 : AnyObjectId otherCommitId, AnyObjectId newId, Whitespace whitespace) {
59 0 : return new PatchListKey(otherCommitId, newId, whitespace);
60 : }
61 :
62 : public static PatchListKey againstBase(ObjectId id, int parentCount) {
63 103 : return parentCount > 1
64 30 : ? PatchListKey.againstParentNum(1, id, Whitespace.IGNORE_NONE)
65 103 : : PatchListKey.againstDefaultBase(id, Whitespace.IGNORE_NONE);
66 : }
67 :
68 : /**
69 : * Old patch-set ID
70 : *
71 : * <p>When null, it represents the Base of the newId for a non-merge commit.
72 : *
73 : * <p>When newId is a merge commit, null value of the oldId represents either the auto-merge
74 : * commit of the newId or a parent commit of the newId. These two cases are distinguished by the
75 : * parentNum.
76 : */
77 : private transient ObjectId oldId;
78 :
79 : /**
80 : * 1-based parent number when newId is a merge commit
81 : *
82 : * <p>For the auto-merge case this field is null.
83 : *
84 : * <p>Used only when oldId is null and newId is a merge commit
85 : */
86 : private transient Integer parentNum;
87 :
88 : private transient ObjectId newId;
89 : private transient Whitespace whitespace;
90 :
91 103 : private PatchListKey(AnyObjectId a, AnyObjectId b, Whitespace ws) {
92 103 : oldId = ObjectIds.copyOrNull(a);
93 103 : newId = b.copy();
94 103 : whitespace = ws;
95 103 : }
96 :
97 30 : private PatchListKey(int parentNum, AnyObjectId b, Whitespace ws) {
98 30 : this.parentNum = Integer.valueOf(parentNum);
99 30 : newId = b.copy();
100 30 : whitespace = ws;
101 30 : }
102 :
103 : /** For use only by DiffSummaryKey. */
104 103 : PatchListKey(ObjectId oldId, Integer parentNum, ObjectId newId, Whitespace whitespace) {
105 103 : this.oldId = oldId;
106 103 : this.parentNum = parentNum;
107 103 : this.newId = newId;
108 103 : this.whitespace = whitespace;
109 103 : }
110 :
111 : /** Old side commit, or null to assume ancestor or combined merge. */
112 : @Nullable
113 : public ObjectId getOldId() {
114 103 : return oldId;
115 : }
116 :
117 : /** Parent number (old side) of the new side (merge) commit */
118 : @Nullable
119 : public Integer getParentNum() {
120 103 : return parentNum;
121 : }
122 :
123 : /** New side commit name. */
124 : public ObjectId getNewId() {
125 103 : return newId;
126 : }
127 :
128 : public Whitespace getWhitespace() {
129 103 : return whitespace;
130 : }
131 :
132 : @Override
133 : public int hashCode() {
134 0 : return Objects.hash(oldId, parentNum, newId, whitespace);
135 : }
136 :
137 : @Override
138 : public boolean equals(Object o) {
139 0 : if (o instanceof PatchListKey) {
140 0 : PatchListKey k = (PatchListKey) o;
141 0 : return Objects.equals(oldId, k.oldId)
142 0 : && Objects.equals(parentNum, k.parentNum)
143 0 : && Objects.equals(newId, k.newId)
144 : && whitespace == k.whitespace;
145 : }
146 0 : return false;
147 : }
148 :
149 : @Override
150 : public String toString() {
151 0 : StringBuilder n = new StringBuilder();
152 0 : n.append("PatchListKey[");
153 0 : n.append(oldId != null ? oldId.name() : "BASE");
154 0 : n.append("..");
155 0 : n.append(newId.name());
156 0 : n.append(" ");
157 0 : if (parentNum != null) {
158 0 : n.append(parentNum);
159 0 : n.append(" ");
160 : }
161 0 : n.append(whitespace.name());
162 0 : n.append("]");
163 0 : return n.toString();
164 : }
165 :
166 : private void writeObject(ObjectOutputStream out) throws IOException {
167 0 : write(out, oldId);
168 0 : out.writeInt(parentNum == null ? 0 : parentNum);
169 0 : writeWithoutMarker(out, newId);
170 0 : Character c = WHITESPACE_TYPES.get(whitespace);
171 0 : if (c == null) {
172 0 : throw new IOException("Invalid whitespace type: " + whitespace);
173 : }
174 0 : out.writeChar(c);
175 0 : }
176 :
177 : private void readObject(ObjectInputStream in) throws IOException {
178 0 : oldId = read(in);
179 0 : int n = in.readInt();
180 0 : parentNum = n == 0 ? null : Integer.valueOf(n);
181 0 : newId = readWithoutMarker(in);
182 0 : char t = in.readChar();
183 0 : whitespace = WHITESPACE_TYPES.inverse().get(t);
184 0 : if (whitespace == null) {
185 0 : throw new IOException("Invalid whitespace type code: " + t);
186 : }
187 0 : }
188 : }
|