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