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 Map<String, String> pushInsteadOf = getReplacements(rc,
177 KEY_PUSHINSTEADOF);
178 vlst = rc.getStringList(SECTION, name, KEY_PUSHURL);
179 pushURIs = new ArrayList<>(vlst.length);
180 for (final String s : vlst)
181 pushURIs.add(new URIish(replaceUri(s, pushInsteadOf)));
182
183 vlst = rc.getStringList(SECTION, name, KEY_FETCH);
184 fetch = new ArrayList<>(vlst.length);
185 for (final String s : vlst)
186 fetch.add(new RefSpec(s));
187
188 vlst = rc.getStringList(SECTION, name, KEY_PUSH);
189 push = new ArrayList<>(vlst.length);
190 for (final String s : vlst)
191 push.add(new RefSpec(s));
192
193 val = rc.getString(SECTION, name, KEY_UPLOADPACK);
194 if (val == null)
195 val = DEFAULT_UPLOAD_PACK;
196 uploadpack = val;
197
198 val = rc.getString(SECTION, name, KEY_RECEIVEPACK);
199 if (val == null)
200 val = DEFAULT_RECEIVE_PACK;
201 receivepack = val;
202
203 val = rc.getString(SECTION, name, KEY_TAGOPT);
204 tagopt = TagOpt.fromOption(val);
205 mirror = rc.getBoolean(SECTION, name, KEY_MIRROR, DEFAULT_MIRROR);
206 timeout = rc.getInt(SECTION, name, KEY_TIMEOUT, 0);
207 }
208
209
210
211
212
213
214
215 public void update(final Config rc) {
216 final List<String> vlst = new ArrayList<>();
217
218 vlst.clear();
219 for (final URIish u : getURIs())
220 vlst.add(u.toPrivateString());
221 rc.setStringList(SECTION, getName(), KEY_URL, vlst);
222
223 vlst.clear();
224 for (final URIish u : getPushURIs())
225 vlst.add(u.toPrivateString());
226 rc.setStringList(SECTION, getName(), KEY_PUSHURL, vlst);
227
228 vlst.clear();
229 for (final RefSpec u : getFetchRefSpecs())
230 vlst.add(u.toString());
231 rc.setStringList(SECTION, getName(), KEY_FETCH, vlst);
232
233 vlst.clear();
234 for (final RefSpec u : getPushRefSpecs())
235 vlst.add(u.toString());
236 rc.setStringList(SECTION, getName(), KEY_PUSH, vlst);
237
238 set(rc, KEY_UPLOADPACK, getUploadPack(), DEFAULT_UPLOAD_PACK);
239 set(rc, KEY_RECEIVEPACK, getReceivePack(), DEFAULT_RECEIVE_PACK);
240 set(rc, KEY_TAGOPT, getTagOpt().option(), TagOpt.AUTO_FOLLOW.option());
241 set(rc, KEY_MIRROR, mirror, DEFAULT_MIRROR);
242 set(rc, KEY_TIMEOUT, timeout, 0);
243 }
244
245 private void set(final Config rc, final String key,
246 final String currentValue, final String defaultValue) {
247 if (defaultValue.equals(currentValue))
248 unset(rc, key);
249 else
250 rc.setString(SECTION, getName(), key, currentValue);
251 }
252
253 private void set(final Config rc, final String key,
254 final boolean currentValue, final boolean defaultValue) {
255 if (defaultValue == currentValue)
256 unset(rc, key);
257 else
258 rc.setBoolean(SECTION, getName(), key, currentValue);
259 }
260
261 private void set(final Config rc, final String key, final int currentValue,
262 final int defaultValue) {
263 if (defaultValue == currentValue)
264 unset(rc, key);
265 else
266 rc.setInt(SECTION, getName(), key, currentValue);
267 }
268
269 private void unset(final Config rc, final String key) {
270 rc.unset(SECTION, getName(), key);
271 }
272
273 private Map<String, String> getReplacements(final Config config,
274 final String keyName) {
275 final Map<String, String> replacements = new HashMap<>();
276 for (String url : config.getSubsections(KEY_URL))
277 for (String insteadOf : config.getStringList(KEY_URL, url, keyName))
278 replacements.put(insteadOf, url);
279 return replacements;
280 }
281
282 private String replaceUri(final String uri,
283 final Map<String, String> replacements) {
284 if (replacements.isEmpty())
285 return uri;
286 Entry<String, String> match = null;
287 for (Entry<String, String> replacement : replacements.entrySet()) {
288
289 if (match != null
290 && match.getKey().length() > replacement.getKey().length())
291 continue;
292 if (!uri.startsWith(replacement.getKey()))
293 continue;
294 match = replacement;
295 }
296 if (match != null)
297 return match.getValue() + uri.substring(match.getKey().length());
298 else
299 return uri;
300 }
301
302
303
304
305
306
307 public String getName() {
308 return name;
309 }
310
311
312
313
314
315
316 public List<URIish> getURIs() {
317 return Collections.unmodifiableList(uris);
318 }
319
320
321
322
323
324
325
326
327 public boolean addURI(final URIish toAdd) {
328 if (uris.contains(toAdd))
329 return false;
330 return uris.add(toAdd);
331 }
332
333
334
335
336
337
338
339
340 public boolean removeURI(final URIish toRemove) {
341 return uris.remove(toRemove);
342 }
343
344
345
346
347
348
349 public List<URIish> getPushURIs() {
350 return Collections.unmodifiableList(pushURIs);
351 }
352
353
354
355
356
357
358
359
360 public boolean addPushURI(final URIish toAdd) {
361 if (pushURIs.contains(toAdd))
362 return false;
363 return pushURIs.add(toAdd);
364 }
365
366
367
368
369
370
371
372
373 public boolean removePushURI(final URIish toRemove) {
374 return pushURIs.remove(toRemove);
375 }
376
377
378
379
380
381
382 public List<RefSpec> getFetchRefSpecs() {
383 return Collections.unmodifiableList(fetch);
384 }
385
386
387
388
389
390
391
392
393 public boolean addFetchRefSpec(final RefSpec s) {
394 if (fetch.contains(s))
395 return false;
396 return fetch.add(s);
397 }
398
399
400
401
402
403
404
405
406 public void setFetchRefSpecs(final List<RefSpec> specs) {
407 fetch.clear();
408 fetch.addAll(specs);
409 }
410
411
412
413
414
415
416
417
418 public void setPushRefSpecs(final List<RefSpec> specs) {
419 push.clear();
420 push.addAll(specs);
421 }
422
423
424
425
426
427
428
429
430 public boolean removeFetchRefSpec(final RefSpec s) {
431 return fetch.remove(s);
432 }
433
434
435
436
437
438
439 public List<RefSpec> getPushRefSpecs() {
440 return Collections.unmodifiableList(push);
441 }
442
443
444
445
446
447
448
449
450 public boolean addPushRefSpec(final RefSpec s) {
451 if (push.contains(s))
452 return false;
453 return push.add(s);
454 }
455
456
457
458
459
460
461
462
463 public boolean removePushRefSpec(final RefSpec s) {
464 return push.remove(s);
465 }
466
467
468
469
470
471
472
473
474
475
476
477
478 public String getUploadPack() {
479 return uploadpack;
480 }
481
482
483
484
485
486
487
488
489
490
491
492
493 public String getReceivePack() {
494 return receivepack;
495 }
496
497
498
499
500
501
502 public TagOpt getTagOpt() {
503 return tagopt;
504 }
505
506
507
508
509
510
511
512 public void setTagOpt(final TagOpt option) {
513 tagopt = option != null ? option : TagOpt.AUTO_FOLLOW;
514 }
515
516
517
518
519
520 public boolean isMirror() {
521 return mirror;
522 }
523
524
525
526
527
528
529
530 public void setMirror(final boolean m) {
531 mirror = m;
532 }
533
534
535 public int getTimeout() {
536 return timeout;
537 }
538
539
540
541
542
543
544
545
546
547 public void setTimeout(final int seconds) {
548 timeout = seconds;
549 }
550 }