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