1 package org.apache.maven.scm.provider.svn;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.util.ArrayList;
24 import java.util.List;
25
26 import org.apache.maven.scm.CommandParameters;
27 import org.apache.maven.scm.ScmException;
28 import org.apache.maven.scm.ScmFileSet;
29 import org.apache.maven.scm.ScmResult;
30 import org.apache.maven.scm.command.add.AddScmResult;
31 import org.apache.maven.scm.command.blame.BlameScmResult;
32 import org.apache.maven.scm.command.branch.BranchScmResult;
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.export.ExportScmResult;
38 import org.apache.maven.scm.command.info.InfoItem;
39 import org.apache.maven.scm.command.info.InfoScmResult;
40 import org.apache.maven.scm.command.list.ListScmResult;
41 import org.apache.maven.scm.command.mkdir.MkdirScmResult;
42 import org.apache.maven.scm.command.remove.RemoveScmResult;
43 import org.apache.maven.scm.command.status.StatusScmResult;
44 import org.apache.maven.scm.command.tag.TagScmResult;
45 import org.apache.maven.scm.command.update.UpdateScmResult;
46 import org.apache.maven.scm.provider.AbstractScmProvider;
47 import org.apache.maven.scm.provider.ScmProviderRepository;
48 import org.apache.maven.scm.provider.svn.command.SvnCommand;
49 import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
50 import org.apache.maven.scm.provider.svn.util.SvnUtil;
51 import org.apache.maven.scm.repository.ScmRepositoryException;
52 import org.apache.maven.scm.repository.UnknownRepositoryStructure;
53 import org.codehaus.plexus.util.StringUtils;
54
55
56
57
58
59
60
61 public abstract class AbstractSvnScmProvider
62 extends AbstractScmProvider
63 {
64
65
66
67
68 private static class ScmUrlParserResult
69 {
70 private List<String> messages = new ArrayList<String>();
71
72 private ScmProviderRepository repository;
73 }
74
75 private static final String CHECK_WORKING_DIRECTORY_URL = "scmCheckWorkingDirectoryUrl";
76
77
78
79
80
81
82
83
84 public String getScmSpecificFilename()
85 {
86 return ".svn";
87 }
88
89
90
91
92 public ScmProviderRepository makeProviderScmRepository( String scmSpecificUrl, char delimiter )
93 throws ScmRepositoryException
94 {
95 ScmUrlParserResult result = parseScmUrl( scmSpecificUrl );
96
97 if ( checkWorkingDirectoryUrl() )
98 {
99 getLogger().debug( "Checking svn info 'URL:' field matches current sources directory" );
100 try
101 {
102 InfoScmResult info =
103 info( result.repository, new ScmFileSet( new File( "." ) ), new CommandParameters() );
104 String url = findUrlInfoItem( info );
105 if ( url != null && !url.equals( scmSpecificUrl ) )
106 {
107 result.messages.add( "The scm url does not match the value returned by svn info" );
108 }
109 }
110 catch ( ScmException e )
111 {
112 throw new ScmRepositoryException( "An error occurred while trying to svn info", e );
113 }
114 }
115 if ( result.messages.size() > 0 )
116 {
117 throw new ScmRepositoryException( "The scm url is invalid.", result.messages );
118 }
119
120
121 return result.repository;
122 }
123
124 private boolean checkWorkingDirectoryUrl()
125 {
126 return Boolean.getBoolean( CHECK_WORKING_DIRECTORY_URL );
127 }
128
129 private String findUrlInfoItem( InfoScmResult infoScmResult )
130 {
131 for ( InfoItem infoItem : infoScmResult.getInfoItems() )
132 {
133 if ( infoItem.getURL() != null )
134 {
135 getLogger().debug( "URL found: " + infoItem.getURL() );
136 return infoItem.getURL();
137 }
138 }
139 return null;
140 }
141
142
143
144
145 public ScmProviderRepository makeProviderScmRepository( File path )
146 throws ScmRepositoryException, UnknownRepositoryStructure
147 {
148 if ( path == null )
149 {
150 throw new NullPointerException( "Path argument is null" );
151 }
152
153 if ( !path.isDirectory() )
154 {
155 throw new ScmRepositoryException( path.getAbsolutePath() + " isn't a valid directory." );
156 }
157
158 if ( !new File( path, ".svn" ).exists() )
159 {
160 throw new ScmRepositoryException( path.getAbsolutePath() + " isn't a svn checkout directory." );
161 }
162
163 try
164 {
165 return makeProviderScmRepository( getRepositoryURL( path ), ':' );
166 }
167 catch ( ScmException e )
168 {
169
170 throw new ScmRepositoryException( "Error executing info command", e );
171 }
172 }
173
174 protected abstract String getRepositoryURL( File path )
175 throws ScmException;
176
177
178
179
180 public List<String> validateScmUrl( String scmSpecificUrl, char delimiter )
181 {
182 List<String> messages = new ArrayList<String>();
183 try
184 {
185 makeProviderScmRepository( scmSpecificUrl, delimiter );
186 }
187 catch ( ScmRepositoryException e )
188 {
189 messages = e.getValidationMessages();
190 }
191 return messages;
192 }
193
194
195
196
197 public String getScmType()
198 {
199 return "svn";
200 }
201
202
203
204
205
206 private ScmUrlParserResult parseScmUrl( String scmSpecificUrl )
207 {
208 ScmUrlParserResult result = new ScmUrlParserResult();
209
210 String url = scmSpecificUrl;
211
212
213
214
215
216 if ( url.startsWith( "file" ) )
217 {
218 if ( !url.startsWith( "file://" ) )
219 {
220 result.messages.add( "A svn 'file' url must be on the form 'file://[hostname]/'." );
221
222 return result;
223 }
224 }
225 else if ( url.startsWith( "https" ) )
226 {
227 if ( !url.startsWith( "https://" ) )
228 {
229 result.messages.add( "A svn 'http' url must be on the form 'https://'." );
230
231 return result;
232 }
233 }
234 else if ( url.startsWith( "http" ) )
235 {
236 if ( !url.startsWith( "http://" ) )
237 {
238 result.messages.add( "A svn 'http' url must be on the form 'http://'." );
239
240 return result;
241 }
242 }
243
244 else if ( url.startsWith( "svn+" ) )
245 {
246 if ( url.indexOf( "://" ) < 0 )
247 {
248 result.messages.add( "A svn 'svn+xxx' url must be on the form 'svn+xxx://'." );
249
250 return result;
251 }
252 else
253 {
254 String tunnel = url.substring( "svn+".length(), url.indexOf( "://" ) );
255
256
257 if ( !"ssh".equals( tunnel ) )
258 {
259 SvnConfigFileReader reader = new SvnConfigFileReader();
260 if ( SvnUtil.getSettings().getConfigDirectory() != null )
261 {
262 reader.setConfigDirectory( new File( SvnUtil.getSettings().getConfigDirectory() ) );
263 }
264
265 if ( StringUtils.isEmpty( reader.getProperty( "tunnels", tunnel ) ) )
266 {
267 result.messages.add(
268 "The tunnel '" + tunnel + "' isn't defined in your subversion configuration file." );
269
270 return result;
271 }
272 }
273 }
274 }
275 else if ( url.startsWith( "svn" ) )
276 {
277 if ( !url.startsWith( "svn://" ) )
278 {
279 result.messages.add( "A svn 'svn' url must be on the form 'svn://'." );
280
281 return result;
282 }
283 }
284 else
285 {
286 result.messages.add( url + " url isn't a valid svn URL." );
287
288 return result;
289 }
290
291 result.repository = new SvnScmProviderRepository( url );
292
293 return result;
294 }
295
296 protected abstract SvnCommand getAddCommand();
297
298
299
300
301 public AddScmResult add( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
302 throws ScmException
303 {
304 return (AddScmResult) executeCommand( getAddCommand(), repository, fileSet, parameters );
305 }
306
307 protected abstract SvnCommand getBranchCommand();
308
309
310
311
312 protected BranchScmResult branch( ScmProviderRepository repository, ScmFileSet fileSet,
313 CommandParameters parameters )
314 throws ScmException
315 {
316 return (BranchScmResult) executeCommand( getBranchCommand(), repository, fileSet, parameters );
317 }
318
319 protected abstract SvnCommand getChangeLogCommand();
320
321
322
323
324 public ChangeLogScmResult changelog( ScmProviderRepository repository, ScmFileSet fileSet,
325 CommandParameters parameters )
326 throws ScmException
327 {
328 return (ChangeLogScmResult) executeCommand( getChangeLogCommand(), repository, fileSet, parameters );
329 }
330
331 protected abstract SvnCommand getCheckInCommand();
332
333
334
335
336 public CheckInScmResult checkin( ScmProviderRepository repository, ScmFileSet fileSet,
337 CommandParameters parameters )
338 throws ScmException
339 {
340 return (CheckInScmResult) executeCommand( getCheckInCommand(), repository, fileSet, parameters );
341 }
342
343 protected abstract SvnCommand getCheckOutCommand();
344
345
346
347
348 public CheckOutScmResult checkout( ScmProviderRepository repository, ScmFileSet fileSet,
349 CommandParameters parameters )
350 throws ScmException
351 {
352 return (CheckOutScmResult) executeCommand( getCheckOutCommand(), repository, fileSet, parameters );
353 }
354
355 protected abstract SvnCommand getDiffCommand();
356
357
358
359
360 public DiffScmResult diff( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
361 throws ScmException
362 {
363 return (DiffScmResult) executeCommand( getDiffCommand(), repository, fileSet, parameters );
364 }
365
366 protected abstract SvnCommand getExportCommand();
367
368
369
370
371 protected ExportScmResult export( ScmProviderRepository repository, ScmFileSet fileSet,
372 CommandParameters parameters )
373 throws ScmException
374 {
375 return (ExportScmResult) executeCommand( getExportCommand(), repository, fileSet, parameters );
376 }
377
378 protected abstract SvnCommand getRemoveCommand();
379
380
381
382
383 public RemoveScmResult remove( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
384 throws ScmException
385 {
386 return (RemoveScmResult) executeCommand( getRemoveCommand(), repository, fileSet, parameters );
387 }
388
389 protected abstract SvnCommand getStatusCommand();
390
391
392
393
394 public StatusScmResult status( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
395 throws ScmException
396 {
397 return (StatusScmResult) executeCommand( getStatusCommand(), repository, fileSet, parameters );
398 }
399
400 protected abstract SvnCommand getTagCommand();
401
402
403
404
405 public TagScmResult tag( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
406 throws ScmException
407 {
408 return (TagScmResult) executeCommand( getTagCommand(), repository, fileSet, parameters );
409 }
410
411 protected abstract SvnCommand getUpdateCommand();
412
413
414
415
416 public UpdateScmResult update( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
417 throws ScmException
418 {
419 return (UpdateScmResult) executeCommand( getUpdateCommand(), repository, fileSet, parameters );
420 }
421
422 protected ScmResult executeCommand( SvnCommand command, ScmProviderRepository repository, ScmFileSet fileSet,
423 CommandParameters parameters )
424 throws ScmException
425 {
426 command.setLogger( getLogger() );
427
428 return command.execute( repository, fileSet, parameters );
429 }
430
431 protected abstract SvnCommand getListCommand();
432
433
434
435
436 public ListScmResult list( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
437 throws ScmException
438 {
439 SvnCommand cmd = getListCommand();
440
441 return (ListScmResult) executeCommand( cmd, repository, fileSet, parameters );
442 }
443
444 protected abstract SvnCommand getInfoCommand();
445
446 public InfoScmResult info( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
447 throws ScmException
448 {
449 SvnCommand cmd = getInfoCommand();
450
451 return (InfoScmResult) executeCommand( cmd, repository, fileSet, parameters );
452 }
453
454
455
456
457 protected BlameScmResult blame( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
458 throws ScmException
459 {
460 SvnCommand cmd = getBlameCommand();
461
462 return (BlameScmResult) executeCommand( cmd, repository, fileSet, parameters );
463 }
464
465 protected abstract SvnCommand getBlameCommand();
466
467
468
469
470 public MkdirScmResult mkdir( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
471 throws ScmException
472 {
473 SvnCommand cmd = getMkdirCommand();
474
475 return (MkdirScmResult) executeCommand( cmd, repository, fileSet, parameters );
476 }
477
478 protected abstract SvnCommand getMkdirCommand();
479
480
481
482
483
484
485
486
487 public abstract boolean remoteUrlExist( ScmProviderRepository repository, CommandParameters parameters )
488 throws ScmException;
489 }