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