1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.linecorp.centraldogma.common;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static java.util.Objects.requireNonNull;
21
22 import java.util.regex.Pattern;
23
24 import javax.annotation.Nullable;
25
26 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
27 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
28
29 import com.linecorp.centraldogma.internal.Util;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 @JsonSerialize(using = RevisionJsonSerializer.class)
48 @JsonDeserialize(using = RevisionJsonDeserializer.class)
49 public class Revision implements Comparable<Revision> {
50
51 private static final Pattern REVISION_PATTERN = Pattern.compile("^-?[0-9]+(?:\\.0)?$");
52
53
54
55
56 public static final Revision HEAD = new Revision(-1);
57
58
59
60
61 public static final Revision INIT = new Revision(1);
62
63 private final int major;
64 private final String text;
65
66
67
68
69 public Revision(int major) {
70 if (major == 0) {
71 throw new IllegalArgumentException("major: 0 (expected: a non-zero integer)");
72 }
73
74 this.major = major;
75 text = generateText(major);
76 }
77
78
79
80
81
82
83 @Deprecated
84 public Revision(int major, int minor) {
85 this(major);
86 checkArgument(minor == 0, "minor: %s (expected: 0)", minor);
87 }
88
89
90
91
92 public Revision(String revisionStr) {
93 requireNonNull(revisionStr, "revisionStr");
94 if ("head".equalsIgnoreCase(revisionStr) || "-1".equals(revisionStr)) {
95 major = HEAD.major;
96 } else {
97 if (!REVISION_PATTERN.matcher(revisionStr).matches()) {
98 throw illegalRevisionArgumentException(revisionStr);
99 }
100
101 try {
102 major = Integer.parseInt(
103 !revisionStr.endsWith(".0") ? revisionStr
104 : revisionStr.substring(0, revisionStr.length() - 2));
105 if (major == 0) {
106 throw illegalRevisionArgumentException(revisionStr);
107 }
108 } catch (NumberFormatException ignored) {
109 throw illegalRevisionArgumentException(revisionStr);
110 }
111 }
112 text = generateText(major);
113 }
114
115
116
117
118 public int major() {
119 return major;
120 }
121
122
123
124
125
126
127 @Deprecated
128 public int minor() {
129 return 0;
130 }
131
132
133
134
135 public String text() {
136 return text;
137 }
138
139
140
141
142
143
144 @Deprecated
145 public boolean onMainLane() {
146 return true;
147 }
148
149
150
151
152
153
154 public Revision backward(int count) {
155 if (count == 0) {
156 return this;
157 }
158 if (count < 0) {
159 throw new IllegalArgumentException("count " + count + " (expected: a non-negative integer)");
160 }
161
162 return new Revision(subtract(major, count));
163 }
164
165 private static int subtract(int revNum, int delta) {
166 if (revNum > 0) {
167 return Math.max(1, revNum - delta);
168 } else {
169 if (revNum < Integer.MIN_VALUE + delta) {
170 return Integer.MIN_VALUE;
171 } else {
172 return revNum - delta;
173 }
174 }
175 }
176
177
178
179
180
181
182 public Revision forward(int count) {
183 if (count == 0) {
184 return this;
185 }
186 if (count < 0) {
187 throw new IllegalArgumentException("count " + count + " (expected: a non-negative integer)");
188 }
189
190 return new Revision(add(major, count));
191 }
192
193 private static int add(int revNum, int delta) {
194 if (revNum > 0) {
195 if (revNum > Integer.MAX_VALUE - delta) {
196 return Integer.MAX_VALUE;
197 } else {
198 return revNum + delta;
199 }
200 } else {
201 return Math.min(-1, revNum + delta);
202 }
203 }
204
205 @Override
206 public int hashCode() {
207 return major;
208 }
209
210 @Override
211 public boolean equals(@Nullable Object o) {
212 if (this == o) {
213 return true;
214 }
215 if (!(o instanceof Revision)) {
216 return false;
217 }
218
219 return major == ((Revision) o).major;
220 }
221
222 @Override
223 public String toString() {
224
225 final StringBuilder buf = new StringBuilder();
226
227 buf.append(Util.simpleTypeName(this));
228 buf.append('(');
229 buf.append(major);
230 buf.append(')');
231
232 return buf.toString();
233 }
234
235 @Override
236 public int compareTo(Revision o) {
237 return Integer.compare(major, o.major);
238 }
239
240
241
242
243 public boolean isRelative() {
244 return major < 0;
245 }
246
247 private static String generateText(int major) {
248 return String.valueOf(major);
249 }
250
251 private static IllegalArgumentException illegalRevisionArgumentException(String revisionStr) {
252 return new IllegalArgumentException(
253 "revisionStr: " + revisionStr +
254 " (expected: \"major\" or \"major.0\" where major is non-zero integer)");
255 }
256 }