1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.transport;
12
13 import java.io.Serializable;
14 import java.text.MessageFormat;
15
16 import org.eclipse.jgit.internal.JGitText;
17 import org.eclipse.jgit.lib.Constants;
18 import org.eclipse.jgit.lib.Ref;
19 import org.eclipse.jgit.util.References;
20
21
22
23
24
25
26
27 public class RefSpec implements Serializable {
28 private static final long serialVersionUID = 1L;
29
30
31
32
33
34 public static final String WILDCARD_SUFFIX = "/*";
35
36
37
38
39
40
41
42
43 public static boolean isWildcard(String s) {
44 return s != null && s.contains("*");
45 }
46
47
48 private boolean force;
49
50
51 private boolean wildcard;
52
53
54
55
56
57
58 public enum WildcardMode {
59
60
61
62
63
64
65 REQUIRE_MATCH,
66
67
68
69
70
71
72 ALLOW_MISMATCH
73 }
74
75 private WildcardMode allowMismatchedWildcards;
76
77
78 private String srcName;
79
80
81 private String dstName;
82
83
84
85
86
87
88
89 public RefSpec() {
90 force = false;
91 wildcard = false;
92 srcName = Constants.HEAD;
93 dstName = null;
94 allowMismatchedWildcards = WildcardMode.REQUIRE_MATCH;
95 }
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 public RefSpec(String spec, WildcardMode mode) {
129 this.allowMismatchedWildcards = mode;
130 String s = spec;
131 if (s.startsWith("+")) {
132 force = true;
133 s = s.substring(1);
134 }
135
136 final int c = s.lastIndexOf(':');
137 if (c == 0) {
138 s = s.substring(1);
139 if (isWildcard(s)) {
140 wildcard = true;
141 if (mode == WildcardMode.REQUIRE_MATCH) {
142 throw new IllegalArgumentException(MessageFormat
143 .format(JGitText.get().invalidWildcards, spec));
144 }
145 }
146 dstName = checkValid(s);
147 } else if (c > 0) {
148 String src = s.substring(0, c);
149 String dst = s.substring(c + 1);
150 if (isWildcard(src) && isWildcard(dst)) {
151
152 wildcard = true;
153 } else if (isWildcard(src) || isWildcard(dst)) {
154 wildcard = true;
155 if (mode == WildcardMode.REQUIRE_MATCH)
156 throw new IllegalArgumentException(MessageFormat
157 .format(JGitText.get().invalidWildcards, spec));
158 }
159 srcName = checkValid(src);
160 dstName = checkValid(dst);
161 } else {
162 if (isWildcard(s)) {
163 if (mode == WildcardMode.REQUIRE_MATCH) {
164 throw new IllegalArgumentException(MessageFormat
165 .format(JGitText.get().invalidWildcards, spec));
166 }
167 wildcard = true;
168 }
169 srcName = checkValid(s);
170 }
171 }
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 public RefSpec(String spec) {
194 this(spec, WildcardMode.REQUIRE_MATCH);
195 }
196
197 private RefSpecc" href="../../../../org/eclipse/jgit/transport/RefSpec.html#RefSpec">RefSpec(RefSpec p) {
198 force = p.isForceUpdate();
199 wildcard = p.isWildcard();
200 srcName = p.getSource();
201 dstName = p.getDestination();
202 allowMismatchedWildcards = p.allowMismatchedWildcards;
203 }
204
205
206
207
208
209
210 public boolean isForceUpdate() {
211 return force;
212 }
213
214
215
216
217
218
219
220
221 public RefSpec setForceUpdate(boolean forceUpdate) {
222 final RefSpecrt/RefSpec.html#RefSpec">RefSpec r = new RefSpec(this);
223 r.force = forceUpdate;
224 return r;
225 }
226
227
228
229
230
231
232
233
234
235
236 public boolean isWildcard() {
237 return wildcard;
238 }
239
240
241
242
243
244
245
246
247
248
249 public String getSource() {
250 return srcName;
251 }
252
253
254
255
256
257
258
259
260
261
262
263
264 public RefSpec setSource(String source) {
265 final RefSpecrt/RefSpec.html#RefSpec">RefSpec r = new RefSpec(this);
266 r.srcName = checkValid(source);
267 if (isWildcard(r.srcName) && r.dstName == null)
268 throw new IllegalStateException(JGitText.get().destinationIsNotAWildcard);
269 if (isWildcard(r.srcName) != isWildcard(r.dstName))
270 throw new IllegalStateException(JGitText.get().sourceDestinationMustMatch);
271 return r;
272 }
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288 public String getDestination() {
289 return dstName;
290 }
291
292
293
294
295
296
297
298
299
300
301
302
303 public RefSpec setDestination(String destination) {
304 final RefSpecrt/RefSpec.html#RefSpec">RefSpec r = new RefSpec(this);
305 r.dstName = checkValid(destination);
306 if (isWildcard(r.dstName) && r.srcName == null)
307 throw new IllegalStateException(JGitText.get().sourceIsNotAWildcard);
308 if (isWildcard(r.srcName) != isWildcard(r.dstName))
309 throw new IllegalStateException(JGitText.get().sourceDestinationMustMatch);
310 return r;
311 }
312
313
314
315
316
317
318
319
320
321
322
323
324
325 public RefSpec setSourceDestination(final String source,
326 final String destination) {
327 if (isWildcard(source) != isWildcard(destination))
328 throw new IllegalStateException(JGitText.get().sourceDestinationMustMatch);
329 final RefSpecrt/RefSpec.html#RefSpec">RefSpec r = new RefSpec(this);
330 r.wildcard = isWildcard(source);
331 r.srcName = source;
332 r.dstName = destination;
333 return r;
334 }
335
336
337
338
339
340
341
342
343 public boolean matchSource(String r) {
344 return match(r, getSource());
345 }
346
347
348
349
350
351
352
353
354 public boolean matchSource(Ref r) {
355 return match(r.getName(), getSource());
356 }
357
358
359
360
361
362
363
364
365 public boolean matchDestination(String r) {
366 return match(r, getDestination());
367 }
368
369
370
371
372
373
374
375
376 public boolean matchDestination(Ref r) {
377 return match(r.getName(), getDestination());
378 }
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396 public RefSpec expandFromSource(String r) {
397 if (allowMismatchedWildcards != WildcardMode.REQUIRE_MATCH) {
398 throw new IllegalStateException(
399 JGitText.get().invalidExpandWildcard);
400 }
401 return isWildcard() ? new RefSpec(this).expandFromSourceImp(r) : this;
402 }
403
404 private RefSpec expandFromSourceImp(String name) {
405 final String psrc = srcName, pdst = dstName;
406 wildcard = false;
407 srcName = name;
408 dstName = expandWildcard(name, psrc, pdst);
409 return this;
410 }
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428 public RefSpec expandFromSource(Ref r) {
429 return expandFromSource(r.getName());
430 }
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448 public RefSpec expandFromDestination(String r) {
449 if (allowMismatchedWildcards != WildcardMode.REQUIRE_MATCH) {
450 throw new IllegalStateException(
451 JGitText.get().invalidExpandWildcard);
452 }
453 return isWildcard() ? new RefSpec(this).expandFromDstImp(r) : this;
454 }
455
456 private RefSpec expandFromDstImp(String name) {
457 final String psrc = srcName, pdst = dstName;
458 wildcard = false;
459 srcName = expandWildcard(name, pdst, psrc);
460 dstName = name;
461 return this;
462 }
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479 public RefSpec expandFromDestination(Ref r) {
480 return expandFromDestination(r.getName());
481 }
482
483 private boolean match(String name, String s) {
484 if (s == null)
485 return false;
486 if (isWildcard(s)) {
487 int wildcardIndex = s.indexOf('*');
488 String prefix = s.substring(0, wildcardIndex);
489 String suffix = s.substring(wildcardIndex + 1);
490 return name.length() > prefix.length() + suffix.length()
491 && name.startsWith(prefix) && name.endsWith(suffix);
492 }
493 return name.equals(s);
494 }
495
496 private static String expandWildcard(String name, String patternA,
497 String patternB) {
498 int a = patternA.indexOf('*');
499 int trailingA = patternA.length() - (a + 1);
500 int b = patternB.indexOf('*');
501 String match = name.substring(a, name.length() - trailingA);
502 return patternB.substring(0, b) + match + patternB.substring(b + 1);
503 }
504
505 private static String checkValid(String spec) {
506 if (spec != null && !isValid(spec))
507 throw new IllegalArgumentException(MessageFormat.format(
508 JGitText.get().invalidRefSpec, spec));
509 return spec;
510 }
511
512 private static boolean isValid(String s) {
513 if (s.startsWith("/"))
514 return false;
515 if (s.contains("//")) //$NON-NLS-1$
516 return false;
517 if (s.endsWith("/"))
518 return false;
519 int i = s.indexOf('*');
520 if (i != -1) {
521 if (s.indexOf('*', i + 1) > i)
522 return false;
523 }
524 return true;
525 }
526
527
528 @Override
529 public int hashCode() {
530 int hc = 0;
531 if (getSource() != null)
532 hc = hc * 31 + getSource().hashCode();
533 if (getDestination() != null)
534 hc = hc * 31 + getDestination().hashCode();
535 return hc;
536 }
537
538
539 @Override
540 public boolean equals(Object obj) {
541 if (!(obj instanceof RefSpec))
542 return false;
543 final RefSpecef="../../../../org/eclipse/jgit/transport/RefSpec.html#RefSpec">RefSpec b = (RefSpec) obj;
544 if (isForceUpdate() != b.isForceUpdate())
545 return false;
546 if (isWildcard() != b.isWildcard())
547 return false;
548 if (!eq(getSource(), b.getSource()))
549 return false;
550 if (!eq(getDestination(), b.getDestination()))
551 return false;
552 return true;
553 }
554
555 private static boolean eq(String a, String b) {
556 if (References.isSameObject(a, b)) {
557 return true;
558 }
559 if (a == null || b == null)
560 return false;
561 return a.equals(b);
562 }
563
564
565 @Override
566 public String toString() {
567 final StringBuilder r = new StringBuilder();
568 if (isForceUpdate())
569 r.append('+');
570 if (getSource() != null)
571 r.append(getSource());
572 if (getDestination() != null) {
573 r.append(':');
574 r.append(getDestination());
575 }
576 return r.toString();
577 }
578 }