1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.scm.manager;
20
21 import java.io.File;
22 import java.util.ArrayList;
23 import java.util.Date;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.concurrent.ConcurrentHashMap;
27
28 import org.apache.maven.scm.CommandParameters;
29 import org.apache.maven.scm.ScmBranch;
30 import org.apache.maven.scm.ScmBranchParameters;
31 import org.apache.maven.scm.ScmException;
32 import org.apache.maven.scm.ScmFileSet;
33 import org.apache.maven.scm.ScmTagParameters;
34 import org.apache.maven.scm.ScmVersion;
35 import org.apache.maven.scm.command.add.AddScmResult;
36 import org.apache.maven.scm.command.blame.BlameScmRequest;
37 import org.apache.maven.scm.command.blame.BlameScmResult;
38 import org.apache.maven.scm.command.branch.BranchScmResult;
39 import org.apache.maven.scm.command.changelog.ChangeLogScmRequest;
40 import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
41 import org.apache.maven.scm.command.checkin.CheckInScmResult;
42 import org.apache.maven.scm.command.checkout.CheckOutScmResult;
43 import org.apache.maven.scm.command.diff.DiffScmResult;
44 import org.apache.maven.scm.command.edit.EditScmResult;
45 import org.apache.maven.scm.command.export.ExportScmResult;
46 import org.apache.maven.scm.command.list.ListScmResult;
47 import org.apache.maven.scm.command.mkdir.MkdirScmResult;
48 import org.apache.maven.scm.command.remove.RemoveScmResult;
49 import org.apache.maven.scm.command.status.StatusScmResult;
50 import org.apache.maven.scm.command.tag.TagScmResult;
51 import org.apache.maven.scm.command.unedit.UnEditScmResult;
52 import org.apache.maven.scm.command.update.UpdateScmResult;
53 import org.apache.maven.scm.provider.ScmProvider;
54 import org.apache.maven.scm.provider.ScmProviderRepository;
55 import org.apache.maven.scm.provider.ScmUrlUtils;
56 import org.apache.maven.scm.repository.ScmRepository;
57 import org.apache.maven.scm.repository.ScmRepositoryException;
58 import org.apache.maven.scm.repository.UnknownRepositoryStructure;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62 import static java.util.Objects.requireNonNull;
63
64
65
66
67
68
69 public abstract class AbstractScmManager implements ScmManager {
70 protected final Logger logger = LoggerFactory.getLogger(getClass());
71
72 private final Map<String, ScmProvider> scmProviders = new ConcurrentHashMap<>();
73
74 private final Map<String, String> userProviderTypes = new ConcurrentHashMap<>();
75
76 protected void setScmProviders(Map<String, ScmProvider> providers) {
77 requireNonNull(providers);
78 this.scmProviders.clear();
79
80 providers.forEach(this.scmProviders::putIfAbsent);
81 }
82
83
84
85
86
87
88 @Deprecated
89 protected void addScmProvider(String providerType, ScmProvider provider) {
90 setScmProvider(providerType, provider);
91 }
92
93
94
95
96
97
98
99
100 @Override
101 public void setScmProvider(String providerType, ScmProvider provider) {
102 requireNonNull(providerType);
103 requireNonNull(provider);
104 scmProviders.put(providerType, provider);
105 }
106
107
108
109
110
111
112
113
114 @Override
115 public ScmProvider getProviderByUrl(String scmUrl) throws ScmRepositoryException, NoSuchScmProviderException {
116 requireNonNull(scmUrl, "The scm url cannot be null.");
117
118 String providerType = ScmUrlUtils.getProvider(scmUrl);
119
120 return getProviderByType(providerType);
121 }
122
123
124
125
126 @Override
127 public void setScmProviderImplementation(String providerType, String providerImplementation) {
128 requireNonNull(providerType);
129 requireNonNull(providerImplementation);
130 userProviderTypes.put(providerType, providerImplementation);
131 }
132
133
134
135
136 @Override
137 public ScmProvider getProviderByType(String providerType) throws NoSuchScmProviderException {
138 String usedProviderType = System.getProperty("maven.scm.provider." + providerType + ".implementation");
139
140 if (usedProviderType == null) {
141 usedProviderType = userProviderTypes.getOrDefault(providerType, providerType);
142 }
143
144 ScmProvider scmProvider = scmProviders.get(usedProviderType);
145
146 if (scmProvider == null) {
147 throw new NoSuchScmProviderException(usedProviderType);
148 }
149
150 return scmProvider;
151 }
152
153
154
155
156 @Override
157 public ScmProvider getProviderByRepository(ScmRepository repository) throws NoSuchScmProviderException {
158 return getProviderByType(repository.getProvider());
159 }
160
161
162
163
164
165
166
167
168 @Override
169 public ScmRepository makeScmRepository(String scmUrl) throws ScmRepositoryException, NoSuchScmProviderException {
170 requireNonNull(scmUrl, "The scm url cannot be null.");
171
172 char delimiter = ScmUrlUtils.getDelimiter(scmUrl).charAt(0);
173
174 String providerType = ScmUrlUtils.getProvider(scmUrl);
175
176 ScmProvider provider = getProviderByType(providerType);
177
178 String scmSpecificUrl = cleanScmUrl(scmUrl.substring(providerType.length() + 5));
179
180 ScmProviderRepository providerRepository = provider.makeProviderScmRepository(scmSpecificUrl, delimiter);
181
182 return new ScmRepository(providerType, providerRepository);
183 }
184
185
186
187
188
189
190
191 protected String cleanScmUrl(String scmUrl) {
192 requireNonNull(scmUrl, "The scm url cannot be null.");
193
194 String pathSeparator = "";
195
196 int indexOfDoubleDot = -1;
197
198
199 if (scmUrl.indexOf("../") > 1) {
200 pathSeparator = "/";
201
202 indexOfDoubleDot = scmUrl.indexOf("../");
203 }
204
205
206 if (scmUrl.indexOf("..\\") > 1) {
207 pathSeparator = "\\";
208
209 indexOfDoubleDot = scmUrl.indexOf("..\\");
210 }
211
212 if (indexOfDoubleDot > 1) {
213 int startOfTextToRemove = scmUrl.substring(0, indexOfDoubleDot - 1).lastIndexOf(pathSeparator);
214
215 String beginUrl = "";
216 if (startOfTextToRemove >= 0) {
217 beginUrl = scmUrl.substring(0, startOfTextToRemove);
218 }
219
220 String endUrl = scmUrl.substring(indexOfDoubleDot + 3);
221
222 scmUrl = beginUrl + pathSeparator + endUrl;
223
224
225 if (scmUrl.indexOf("../") > 1 || scmUrl.indexOf("..\\") > 1) {
226 scmUrl = cleanScmUrl(scmUrl);
227 }
228 }
229
230 return scmUrl;
231 }
232
233
234
235
236 @Override
237 public ScmRepository makeProviderScmRepository(String providerType, File path)
238 throws ScmRepositoryException, UnknownRepositoryStructure, NoSuchScmProviderException {
239 requireNonNull(providerType, "The provider type cannot be null.");
240
241 ScmProvider provider = getProviderByType(providerType);
242
243 ScmProviderRepository providerRepository = provider.makeProviderScmRepository(path);
244
245 return new ScmRepository(providerType, providerRepository);
246 }
247
248
249
250
251 @Override
252 public List<String> validateScmRepository(String scmUrl) {
253 List<String> messages = new ArrayList<>(ScmUrlUtils.validate(scmUrl));
254
255 String providerType = ScmUrlUtils.getProvider(scmUrl);
256
257 ScmProvider provider;
258
259 try {
260 provider = getProviderByType(providerType);
261 } catch (NoSuchScmProviderException e) {
262 messages.add("No such provider installed '" + providerType + "'.");
263
264 return messages;
265 }
266
267 String scmSpecificUrl = cleanScmUrl(scmUrl.substring(providerType.length() + 5));
268
269 List<String> providerMessages = provider.validateScmUrl(
270 scmSpecificUrl, ScmUrlUtils.getDelimiter(scmUrl).charAt(0));
271
272 requireNonNull(providerMessages, "The SCM provider cannot return null from validateScmUrl().");
273
274 messages.addAll(providerMessages);
275
276 return messages;
277 }
278
279
280
281
282 @Override
283 public AddScmResult add(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
284 return this.getProviderByRepository(repository).add(repository, fileSet);
285 }
286
287
288
289
290 @Override
291 public AddScmResult add(ScmRepository repository, ScmFileSet fileSet, String message) throws ScmException {
292 return this.getProviderByRepository(repository).add(repository, fileSet, message);
293 }
294
295
296
297
298 @Override
299 public BranchScmResult branch(ScmRepository repository, ScmFileSet fileSet, String branchName) throws ScmException {
300 ScmBranchParameters scmBranchParameters = new ScmBranchParameters("");
301 return this.getProviderByRepository(repository).branch(repository, fileSet, branchName, scmBranchParameters);
302 }
303
304
305
306
307 @Override
308 public BranchScmResult branch(ScmRepository repository, ScmFileSet fileSet, String branchName, String message)
309 throws ScmException {
310 ScmBranchParameters scmBranchParameters = new ScmBranchParameters(message);
311 return this.getProviderByRepository(repository).branch(repository, fileSet, branchName, scmBranchParameters);
312 }
313
314
315
316
317 @Override
318 public ChangeLogScmResult changeLog(
319 ScmRepository repository, ScmFileSet fileSet, Date startDate, Date endDate, int numDays, ScmBranch branch)
320 throws ScmException {
321 return this.getProviderByRepository(repository)
322 .changeLog(repository, fileSet, startDate, endDate, numDays, branch);
323 }
324
325
326
327
328 @Override
329 public ChangeLogScmResult changeLog(
330 ScmRepository repository,
331 ScmFileSet fileSet,
332 Date startDate,
333 Date endDate,
334 int numDays,
335 ScmBranch branch,
336 String datePattern)
337 throws ScmException {
338 return this.getProviderByRepository(repository)
339 .changeLog(repository, fileSet, startDate, endDate, numDays, branch, datePattern);
340 }
341
342
343
344
345 @Override
346 public ChangeLogScmResult changeLog(ChangeLogScmRequest scmRequest) throws ScmException {
347 return this.getProviderByRepository(scmRequest.getScmRepository()).changeLog(scmRequest);
348 }
349
350
351
352
353 @Override
354 public ChangeLogScmResult changeLog(
355 ScmRepository repository, ScmFileSet fileSet, ScmVersion startVersion, ScmVersion endVersion)
356 throws ScmException {
357 return this.getProviderByRepository(repository).changeLog(repository, fileSet, startVersion, endVersion);
358 }
359
360
361
362
363 @Override
364 public ChangeLogScmResult changeLog(
365 ScmRepository repository,
366 ScmFileSet fileSet,
367 ScmVersion startRevision,
368 ScmVersion endRevision,
369 String datePattern)
370 throws ScmException {
371 return this.getProviderByRepository(repository)
372 .changeLog(repository, fileSet, startRevision, endRevision, datePattern);
373 }
374
375
376
377
378 @Override
379 public CheckInScmResult checkIn(ScmRepository repository, ScmFileSet fileSet, String message) throws ScmException {
380 return this.getProviderByRepository(repository).checkIn(repository, fileSet, message);
381 }
382
383
384
385
386 @Override
387 public CheckInScmResult checkIn(ScmRepository repository, ScmFileSet fileSet, ScmVersion revision, String message)
388 throws ScmException {
389 return this.getProviderByRepository(repository).checkIn(repository, fileSet, revision, message);
390 }
391
392 @Override
393 public CheckInScmResult checkIn(ScmRepository repository, ScmFileSet fileSet, CommandParameters commandParameters)
394 throws ScmException {
395 return this.getProviderByRepository(repository).checkIn(repository, fileSet, commandParameters);
396 }
397
398
399
400
401 @Override
402 public CheckOutScmResult checkOut(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
403 return this.getProviderByRepository(repository).checkOut(repository, fileSet);
404 }
405
406
407
408
409 @Override
410 public CheckOutScmResult checkOut(ScmRepository repository, ScmFileSet fileSet, ScmVersion version)
411 throws ScmException {
412 return this.getProviderByRepository(repository).checkOut(repository, fileSet, version);
413 }
414
415
416
417
418 @Override
419 public CheckOutScmResult checkOut(ScmRepository repository, ScmFileSet fileSet, boolean recursive)
420 throws ScmException {
421 return this.getProviderByRepository(repository).checkOut(repository, fileSet, recursive);
422 }
423
424
425
426
427 @Override
428 public CheckOutScmResult checkOut(
429 ScmRepository repository, ScmFileSet fileSet, ScmVersion version, boolean recursive) throws ScmException {
430 return this.getProviderByRepository(repository).checkOut(repository, fileSet, version, recursive);
431 }
432
433
434
435
436 @Override
437 public DiffScmResult diff(
438 ScmRepository repository, ScmFileSet fileSet, ScmVersion startVersion, ScmVersion endVersion)
439 throws ScmException {
440 return this.getProviderByRepository(repository).diff(repository, fileSet, startVersion, endVersion);
441 }
442
443
444
445
446 @Override
447 public EditScmResult edit(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
448 return this.getProviderByRepository(repository).edit(repository, fileSet);
449 }
450
451
452
453
454 @Override
455 public ExportScmResult export(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
456 return this.getProviderByRepository(repository).export(repository, fileSet);
457 }
458
459
460
461
462 @Override
463 public ExportScmResult export(ScmRepository repository, ScmFileSet fileSet, ScmVersion version)
464 throws ScmException {
465 return this.getProviderByRepository(repository).export(repository, fileSet, version);
466 }
467
468
469
470
471 @Override
472 public ExportScmResult export(ScmRepository repository, ScmFileSet fileSet, String outputDirectory)
473 throws ScmException {
474 return this.getProviderByRepository(repository).export(repository, fileSet, (ScmVersion) null, outputDirectory);
475 }
476
477
478
479
480 @Override
481 public ExportScmResult export(
482 ScmRepository repository, ScmFileSet fileSet, ScmVersion version, String outputDirectory)
483 throws ScmException {
484 return this.getProviderByRepository(repository).export(repository, fileSet, version, outputDirectory);
485 }
486
487
488
489
490 @Override
491 public ListScmResult list(ScmRepository repository, ScmFileSet fileSet, boolean recursive, ScmVersion version)
492 throws ScmException {
493 return this.getProviderByRepository(repository).list(repository, fileSet, recursive, version);
494 }
495
496
497
498
499 @Override
500 public MkdirScmResult mkdir(ScmRepository repository, ScmFileSet fileSet, String message, boolean createInLocal)
501 throws ScmException {
502 return this.getProviderByRepository(repository).mkdir(repository, fileSet, message, createInLocal);
503 }
504
505
506
507
508 @Override
509 public RemoveScmResult remove(ScmRepository repository, ScmFileSet fileSet, String message) throws ScmException {
510 return this.getProviderByRepository(repository).remove(repository, fileSet, message);
511 }
512
513
514
515
516 @Override
517 public StatusScmResult status(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
518 return this.getProviderByRepository(repository).status(repository, fileSet);
519 }
520
521
522
523
524 @Override
525 public TagScmResult tag(ScmRepository repository, ScmFileSet fileSet, String tagName) throws ScmException {
526 return this.tag(repository, fileSet, tagName, "");
527 }
528
529
530
531
532 @Override
533 public TagScmResult tag(ScmRepository repository, ScmFileSet fileSet, String tagName, String message)
534 throws ScmException {
535 ScmTagParameters scmTagParameters = new ScmTagParameters(message);
536 return this.getProviderByRepository(repository).tag(repository, fileSet, tagName, scmTagParameters);
537 }
538
539
540
541
542 @Override
543 public UnEditScmResult unedit(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
544 return this.getProviderByRepository(repository).unedit(repository, fileSet);
545 }
546
547
548
549
550 @Override
551 public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet) throws ScmException {
552 return this.getProviderByRepository(repository).update(repository, fileSet);
553 }
554
555
556
557
558 @Override
559 public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, ScmVersion version)
560 throws ScmException {
561 return this.getProviderByRepository(repository).update(repository, fileSet, version);
562 }
563
564
565
566
567 @Override
568 public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, boolean runChangelog)
569 throws ScmException {
570 return this.getProviderByRepository(repository).update(repository, fileSet, runChangelog);
571 }
572
573
574
575
576 @Override
577 public UpdateScmResult update(
578 ScmRepository repository, ScmFileSet fileSet, ScmVersion version, boolean runChangelog)
579 throws ScmException {
580 return this.getProviderByRepository(repository).update(repository, fileSet, version, runChangelog);
581 }
582
583
584
585
586 @Override
587 public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, String datePattern)
588 throws ScmException {
589 return this.getProviderByRepository(repository).update(repository, fileSet, (ScmVersion) null, datePattern);
590 }
591
592
593
594
595 @Override
596 public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, ScmVersion version, String datePattern)
597 throws ScmException {
598 return this.getProviderByRepository(repository).update(repository, fileSet, version, datePattern);
599 }
600
601
602
603
604 @Override
605 public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, Date lastUpdate) throws ScmException {
606 return this.getProviderByRepository(repository).update(repository, fileSet, (ScmVersion) null, lastUpdate);
607 }
608
609
610
611
612 @Override
613 public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, ScmVersion version, Date lastUpdate)
614 throws ScmException {
615 return this.getProviderByRepository(repository).update(repository, fileSet, version, lastUpdate);
616 }
617
618
619
620
621 @Override
622 public UpdateScmResult update(ScmRepository repository, ScmFileSet fileSet, Date lastUpdate, String datePattern)
623 throws ScmException {
624 return this.getProviderByRepository(repository)
625 .update(repository, fileSet, (ScmVersion) null, lastUpdate, datePattern);
626 }
627
628
629
630
631 @Override
632 public UpdateScmResult update(
633 ScmRepository repository, ScmFileSet fileSet, ScmVersion version, Date lastUpdate, String datePattern)
634 throws ScmException {
635 return this.getProviderByRepository(repository).update(repository, fileSet, version, lastUpdate, datePattern);
636 }
637
638
639
640
641 @Override
642 public BlameScmResult blame(ScmRepository repository, ScmFileSet fileSet, String filename) throws ScmException {
643 return this.getProviderByRepository(repository).blame(repository, fileSet, filename);
644 }
645
646 @Override
647 public BlameScmResult blame(BlameScmRequest blameScmRequest) throws ScmException {
648 return this.getProviderByRepository(blameScmRequest.getScmRepository()).blame(blameScmRequest);
649 }
650 }