1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package org.eclipse.jgit.transport;
47
48 import java.io.Serializable;
49 import java.net.URISyntaxException;
50 import java.util.ArrayList;
51 import java.util.Collections;
52 import java.util.HashMap;
53 import java.util.List;
54 import java.util.Map;
55 import java.util.Map.Entry;
56
57 import org.eclipse.jgit.lib.Config;
58
59
60
61
62
63
64
65
66
67 public class RemoteConfig implements Serializable {
68 private static final long serialVersionUID = 1L;
69
70 private static final String SECTION = "remote";
71
72 private static final String KEY_URL = "url";
73
74 private static final String KEY_PUSHURL = "pushurl";
75
76 private static final String KEY_FETCH = "fetch";
77
78 private static final String KEY_PUSH = "push";
79
80 private static final String KEY_UPLOADPACK = "uploadpack";
81
82 private static final String KEY_RECEIVEPACK = "receivepack";
83
84 private static final String KEY_TAGOPT = "tagopt";
85
86 private static final String KEY_MIRROR = "mirror";
87
88 private static final String KEY_TIMEOUT = "timeout";
89
90 private static final String KEY_INSTEADOF = "insteadof";
91
92 private static final String KEY_PUSHINSTEADOF = "pushinsteadof";
93
94 private static final boolean DEFAULT_MIRROR = false;
95
96
97 public static final String DEFAULT_UPLOAD_PACK = "git-upload-pack";
98
99
100 public static final String DEFAULT_RECEIVE_PACK = "git-receive-pack";
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 public static List<RemoteConfig> getAllRemoteConfigs(Config rc)
116 throws URISyntaxException {
117 final List<String> names = new ArrayList<>(rc
118 .getSubsections(SECTION));
119 Collections.sort(names);
120
121 final List<RemoteConfig> result = new ArrayList<>(names
122 .size());
123 for (String name : names)
124 result.add(new RemoteConfig(rc, name));
125 return result;
126 }
127
128 private String name;
129
130 private List<URIish> uris;
131
132 private List<URIish> pushURIs;
133
134 private List<RefSpec> fetch;
135
136 private List<RefSpec> push;
137
138 private String uploadpack;
139
140 private String receivepack;
141
142 private TagOpt tagopt;
143
144 private boolean mirror;
145
146 private int timeout;
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163 public RemoteConfig(Config rc, String remoteName)
164 throws URISyntaxException {
165 name = remoteName;
166
167 String[] vlst;
168 String val;
169
170 vlst = rc.getStringList(SECTION, name, KEY_URL);
171 Map<String, String> insteadOf = getReplacements(rc, KEY_INSTEADOF);
172 uris = new ArrayList<>(vlst.length);
173 for (String s : vlst) {
174 uris.add(new URIish(replaceUri(s, insteadOf)));
175 }
176 String[] plst = rc.getStringList(SECTION, name, KEY_PUSHURL);
177 pushURIs = new ArrayList<>(plst.length);
178 for (String s : plst) {
179 pushURIs.add(new URIish(s));
180 }
181 if (pushURIs.isEmpty()) {
182
183
184 Map<String, String> pushInsteadOf = getReplacements(rc,
185 KEY_PUSHINSTEADOF);
186 if (!pushInsteadOf.isEmpty()) {
187 for (String s : vlst) {
188 String replaced = replaceUri(s, pushInsteadOf);
189 if (!s.equals(replaced)) {
190 pushURIs.add(new URIish(replaced));
191 }
192 }
193 }
194 }
195 fetch = rc.getRefSpecs(SECTION, name, KEY_FETCH);
196 push = rc.getRefSpecs(SECTION, name, KEY_PUSH);
197 val = rc.getString(SECTION, name, KEY_UPLOADPACK);
198 if (val == null) {
199 val = DEFAULT_UPLOAD_PACK;
200 }
201 uploadpack = val;
202
203 val = rc.getString(SECTION, name, KEY_RECEIVEPACK);
204 if (val == null) {
205 val = DEFAULT_RECEIVE_PACK;
206 }
207 receivepack = val;
208
209 try {
210 val = rc.getString(SECTION, name, KEY_TAGOPT);
211 tagopt = TagOpt.fromOption(val);
212 } catch (IllegalArgumentException e) {
213
214 tagopt = TagOpt.AUTO_FOLLOW;
215 }
216 mirror = rc.getBoolean(SECTION, name, KEY_MIRROR, DEFAULT_MIRROR);
217 timeout = rc.getInt(SECTION, name, KEY_TIMEOUT, 0);
218 }
219
220
221
222
223
224
225
226 public void update(Config rc) {
227 final List<String> vlst = new ArrayList<>();
228
229 vlst.clear();
230 for (URIish u : getURIs())
231 vlst.add(u.toPrivateString());
232 rc.setStringList(SECTION, getName(), KEY_URL, vlst);
233
234 vlst.clear();
235 for (URIish u : getPushURIs())
236 vlst.add(u.toPrivateString());
237 rc.setStringList(SECTION, getName(), KEY_PUSHURL, vlst);
238
239 vlst.clear();
240 for (RefSpec u : getFetchRefSpecs())
241 vlst.add(u.toString());
242 rc.setStringList(SECTION, getName(), KEY_FETCH, vlst);
243
244 vlst.clear();
245 for (RefSpec u : getPushRefSpecs())
246 vlst.add(u.toString());
247 rc.setStringList(SECTION, getName(), KEY_PUSH, vlst);
248
249 set(rc, KEY_UPLOADPACK, getUploadPack(), DEFAULT_UPLOAD_PACK);
250 set(rc, KEY_RECEIVEPACK, getReceivePack(), DEFAULT_RECEIVE_PACK);
251 set(rc, KEY_TAGOPT, getTagOpt().option(), TagOpt.AUTO_FOLLOW.option());
252 set(rc, KEY_MIRROR, mirror, DEFAULT_MIRROR);
253 set(rc, KEY_TIMEOUT, timeout, 0);
254 }
255
256 private void set(final Config rc, final String key,
257 final String currentValue, final String defaultValue) {
258 if (defaultValue.equals(currentValue))
259 unset(rc, key);
260 else
261 rc.setString(SECTION, getName(), key, currentValue);
262 }
263
264 private void set(final Config rc, final String key,
265 final boolean currentValue, final boolean defaultValue) {
266 if (defaultValue == currentValue)
267 unset(rc, key);
268 else
269 rc.setBoolean(SECTION, getName(), key, currentValue);
270 }
271
272 private void set(final Config rc, final String key, final int currentValue,
273 final int defaultValue) {
274 if (defaultValue == currentValue)
275 unset(rc, key);
276 else
277 rc.setInt(SECTION, getName(), key, currentValue);
278 }
279
280 private void unset(Config rc, String key) {
281 rc.unset(SECTION, getName(), key);
282 }
283
284 private Map<String, String> getReplacements(final Config config,
285 final String keyName) {
286 final Map<String, String> replacements = new HashMap<>();
287 for (String url : config.getSubsections(KEY_URL))
288 for (String insteadOf : config.getStringList(KEY_URL, url, keyName))
289 replacements.put(insteadOf, url);
290 return replacements;
291 }
292
293 private String replaceUri(final String uri,
294 final Map<String, String> replacements) {
295 if (replacements.isEmpty()) {
296 return uri;
297 }
298 Entry<String, String> match = null;
299 for (Entry<String, String> replacement : replacements.entrySet()) {
300
301 if (match != null
302 && match.getKey().length() > replacement.getKey()
303 .length()) {
304 continue;
305 }
306 if (!uri.startsWith(replacement.getKey())) {
307 continue;
308 }
309 match = replacement;
310 }
311 if (match != null) {
312 return match.getValue() + uri.substring(match.getKey().length());
313 }
314 return uri;
315 }
316
317
318
319
320
321
322 public String getName() {
323 return name;
324 }
325
326
327
328
329
330
331 public List<URIish> getURIs() {
332 return Collections.unmodifiableList(uris);
333 }
334
335
336
337
338
339
340
341
342 public boolean addURI(URIish toAdd) {
343 if (uris.contains(toAdd))
344 return false;
345 return uris.add(toAdd);
346 }
347
348
349
350
351
352
353
354
355 public boolean removeURI(URIish toRemove) {
356 return uris.remove(toRemove);
357 }
358
359
360
361
362
363
364 public List<URIish> getPushURIs() {
365 return Collections.unmodifiableList(pushURIs);
366 }
367
368
369
370
371
372
373
374
375 public boolean addPushURI(URIish toAdd) {
376 if (pushURIs.contains(toAdd))
377 return false;
378 return pushURIs.add(toAdd);
379 }
380
381
382
383
384
385
386
387
388 public boolean removePushURI(URIish toRemove) {
389 return pushURIs.remove(toRemove);
390 }
391
392
393
394
395
396
397 public List<RefSpec> getFetchRefSpecs() {
398 return Collections.unmodifiableList(fetch);
399 }
400
401
402
403
404
405
406
407
408 public boolean addFetchRefSpec(RefSpec s) {
409 if (fetch.contains(s))
410 return false;
411 return fetch.add(s);
412 }
413
414
415
416
417
418
419
420
421 public void setFetchRefSpecs(List<RefSpec> specs) {
422 fetch.clear();
423 fetch.addAll(specs);
424 }
425
426
427
428
429
430
431
432
433 public void setPushRefSpecs(List<RefSpec> specs) {
434 push.clear();
435 push.addAll(specs);
436 }
437
438
439
440
441
442
443
444
445 public boolean removeFetchRefSpec(RefSpec s) {
446 return fetch.remove(s);
447 }
448
449
450
451
452
453
454 public List<RefSpec> getPushRefSpecs() {
455 return Collections.unmodifiableList(push);
456 }
457
458
459
460
461
462
463
464
465 public boolean addPushRefSpec(RefSpec s) {
466 if (push.contains(s))
467 return false;
468 return push.add(s);
469 }
470
471
472
473
474
475
476
477
478 public boolean removePushRefSpec(RefSpec s) {
479 return push.remove(s);
480 }
481
482
483
484
485
486
487
488
489
490
491
492
493 public String getUploadPack() {
494 return uploadpack;
495 }
496
497
498
499
500
501
502
503
504
505
506
507
508 public String getReceivePack() {
509 return receivepack;
510 }
511
512
513
514
515
516
517 public TagOpt getTagOpt() {
518 return tagopt;
519 }
520
521
522
523
524
525
526
527 public void setTagOpt(TagOpt option) {
528 tagopt = option != null ? option : TagOpt.AUTO_FOLLOW;
529 }
530
531
532
533
534
535
536
537
538 public boolean isMirror() {
539 return mirror;
540 }
541
542
543
544
545
546
547
548 public void setMirror(boolean m) {
549 mirror = m;
550 }
551
552
553
554
555
556
557 public int getTimeout() {
558 return timeout;
559 }
560
561
562
563
564
565
566
567
568
569 public void setTimeout(int seconds) {
570 timeout = seconds;
571 }
572 }