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