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(final 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 (final 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(final Config rc, final 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 (final 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 (final 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(final Config rc) {
227 final List<String> vlst = new ArrayList<>();
228
229 vlst.clear();
230 for (final URIish u : getURIs())
231 vlst.add(u.toPrivateString());
232 rc.setStringList(SECTION, getName(), KEY_URL, vlst);
233
234 vlst.clear();
235 for (final URIish u : getPushURIs())
236 vlst.add(u.toPrivateString());
237 rc.setStringList(SECTION, getName(), KEY_PUSHURL, vlst);
238
239 vlst.clear();
240 for (final RefSpec u : getFetchRefSpecs())
241 vlst.add(u.toString());
242 rc.setStringList(SECTION, getName(), KEY_FETCH, vlst);
243
244 vlst.clear();
245 for (final 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(final Config rc, final 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 Entry<String, String> match = null;
298 for (Entry<String, String> replacement : replacements.entrySet()) {
299
300 if (match != null
301 && match.getKey().length() > replacement.getKey().length())
302 continue;
303 if (!uri.startsWith(replacement.getKey()))
304 continue;
305 match = replacement;
306 }
307 if (match != null)
308 return match.getValue() + uri.substring(match.getKey().length());
309 else
310 return uri;
311 }
312
313
314
315
316
317
318 public String getName() {
319 return name;
320 }
321
322
323
324
325
326
327 public List<URIish> getURIs() {
328 return Collections.unmodifiableList(uris);
329 }
330
331
332
333
334
335
336
337
338 public boolean addURI(final URIish toAdd) {
339 if (uris.contains(toAdd))
340 return false;
341 return uris.add(toAdd);
342 }
343
344
345
346
347
348
349
350
351 public boolean removeURI(final URIish toRemove) {
352 return uris.remove(toRemove);
353 }
354
355
356
357
358
359
360 public List<URIish> getPushURIs() {
361 return Collections.unmodifiableList(pushURIs);
362 }
363
364
365
366
367
368
369
370
371 public boolean addPushURI(final URIish toAdd) {
372 if (pushURIs.contains(toAdd))
373 return false;
374 return pushURIs.add(toAdd);
375 }
376
377
378
379
380
381
382
383
384 public boolean removePushURI(final URIish toRemove) {
385 return pushURIs.remove(toRemove);
386 }
387
388
389
390
391
392
393 public List<RefSpec> getFetchRefSpecs() {
394 return Collections.unmodifiableList(fetch);
395 }
396
397
398
399
400
401
402
403
404 public boolean addFetchRefSpec(final RefSpec s) {
405 if (fetch.contains(s))
406 return false;
407 return fetch.add(s);
408 }
409
410
411
412
413
414
415
416
417 public void setFetchRefSpecs(final List<RefSpec> specs) {
418 fetch.clear();
419 fetch.addAll(specs);
420 }
421
422
423
424
425
426
427
428
429 public void setPushRefSpecs(final List<RefSpec> specs) {
430 push.clear();
431 push.addAll(specs);
432 }
433
434
435
436
437
438
439
440
441 public boolean removeFetchRefSpec(final RefSpec s) {
442 return fetch.remove(s);
443 }
444
445
446
447
448
449
450 public List<RefSpec> getPushRefSpecs() {
451 return Collections.unmodifiableList(push);
452 }
453
454
455
456
457
458
459
460
461 public boolean addPushRefSpec(final RefSpec s) {
462 if (push.contains(s))
463 return false;
464 return push.add(s);
465 }
466
467
468
469
470
471
472
473
474 public boolean removePushRefSpec(final RefSpec s) {
475 return push.remove(s);
476 }
477
478
479
480
481
482
483
484
485
486
487
488
489 public String getUploadPack() {
490 return uploadpack;
491 }
492
493
494
495
496
497
498
499
500
501
502
503
504 public String getReceivePack() {
505 return receivepack;
506 }
507
508
509
510
511
512
513 public TagOpt getTagOpt() {
514 return tagopt;
515 }
516
517
518
519
520
521
522
523 public void setTagOpt(final TagOpt option) {
524 tagopt = option != null ? option : TagOpt.AUTO_FOLLOW;
525 }
526
527
528
529
530
531 public boolean isMirror() {
532 return mirror;
533 }
534
535
536
537
538
539
540
541 public void setMirror(final boolean m) {
542 mirror = m;
543 }
544
545
546 public int getTimeout() {
547 return timeout;
548 }
549
550
551
552
553
554
555
556
557
558 public void setTimeout(final int seconds) {
559 timeout = seconds;
560 }
561 }