1 package org.apache.maven.scm.provider.git.repository;
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.ScmException;
23 import org.apache.maven.scm.provider.ScmProviderRepository;
24 import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
25
26 import java.util.regex.Matcher;
27 import java.util.regex.Pattern;
28
29
30
31
32
33
34 public class GitScmProviderRepository
35 extends ScmProviderRepositoryWithHost
36 {
37
38
39
40
41 public static final String URL_DELIMITER_FETCH = "[fetch=]";
42
43
44
45
46 public static final String URL_DELIMITER_PUSH = "[push=]";
47
48
49
50
51 public static final String PROTOCOL_SEPARATOR = "://";
52
53
54
55
56 public static final String PROTOCOL_FILE = "file";
57
58
59
60
61 public static final String PROTOCOL_GIT = "git";
62
63
64
65
66 public static final String PROTOCOL_SSH = "ssh";
67
68
69
70
71 public static final String PROTOCOL_HTTP = "http";
72
73
74
75
76 public static final String PROTOCOL_HTTPS = "https";
77
78
79
80
81
82 public static final String PROTOCOL_RSYNC = "rsync";
83
84 private static final Pattern HOST_AND_PORT_EXTRACTOR =
85 Pattern.compile( "([^:/\\\\~]*)(?::(\\d*))?(?:([:/\\\\~])(.*))?" );
86
87
88
89
90
91 public static final String PROTOCOL_NONE = "";
92
93
94
95
96 private String provider;
97
98
99
100
101 private RepositoryUrl fetchInfo;
102
103
104
105
106 private RepositoryUrl pushInfo;
107
108 public GitScmProviderRepository( String url )
109 throws ScmException
110 {
111 if ( url == null )
112 {
113 throw new ScmException( "url must not be null" );
114 }
115
116 if ( url.startsWith( URL_DELIMITER_FETCH ) )
117 {
118 String fetch = url.substring( URL_DELIMITER_FETCH.length() );
119
120 int indexPushDelimiter = fetch.indexOf( URL_DELIMITER_PUSH );
121 if ( indexPushDelimiter >= 0 )
122 {
123 String push = fetch.substring( indexPushDelimiter + URL_DELIMITER_PUSH.length() );
124 pushInfo = parseUrl( push );
125
126 fetch = fetch.substring( 0, indexPushDelimiter );
127 }
128
129 fetchInfo = parseUrl( fetch );
130
131 if ( pushInfo == null )
132 {
133 pushInfo = fetchInfo;
134 }
135 }
136 else if ( url.startsWith( URL_DELIMITER_PUSH ) )
137 {
138 String push = url.substring( URL_DELIMITER_PUSH.length() );
139
140 int indexFetchDelimiter = push.indexOf( URL_DELIMITER_FETCH );
141 if ( indexFetchDelimiter >= 0 )
142 {
143 String fetch = push.substring( indexFetchDelimiter + URL_DELIMITER_FETCH.length() );
144 fetchInfo = parseUrl( fetch );
145
146 push = push.substring( 0, indexFetchDelimiter );
147 }
148
149 pushInfo = parseUrl( push );
150
151 if ( fetchInfo == null )
152 {
153 fetchInfo = pushInfo;
154 }
155 }
156 else
157 {
158 fetchInfo = pushInfo = parseUrl( url );
159 }
160
161
162
163 setUser( pushInfo.getUserName() );
164 setPassword( pushInfo.getPassword() );
165 setHost( pushInfo.getHost() );
166 if ( pushInfo.getPort() != null && pushInfo.getPort().length() > 0 )
167 {
168 setPort( Integer.parseInt( pushInfo.getPort() ) );
169 }
170 }
171
172 public GitScmProviderRepository( String url, String user, String password )
173 throws ScmException
174 {
175 this( url );
176
177 setUser( user );
178
179 setPassword( password );
180 }
181
182
183
184
185 public String getProvider()
186 {
187 return provider;
188 }
189
190 public RepositoryUrl getFetchInfo()
191 {
192 return fetchInfo;
193 }
194
195 public RepositoryUrl getPushInfo()
196 {
197 return pushInfo;
198 }
199
200
201
202
203
204 public String getFetchUrl()
205 {
206 return getUrl( fetchInfo );
207 }
208
209
210
211
212 public String getPushUrl()
213 {
214 return getUrl( pushInfo );
215 }
216
217
218
219
220
221
222
223
224
225
226 private RepositoryUrl parseUrl( String url )
227 throws ScmException
228 {
229 RepositoryUrl repoUrl = new RepositoryUrl();
230
231 url = parseProtocol( repoUrl, url );
232 url = parseUserInfo( repoUrl, url );
233 url = parseHostAndPort( repoUrl, url );
234
235 repoUrl.setPath( url );
236 return repoUrl;
237 }
238
239
240
241
242
243
244 private String getUrl( RepositoryUrl repoUrl )
245 {
246 StringBuilder urlSb = new StringBuilder( repoUrl.getProtocol() );
247 boolean urlSupportsUserInformation = false;
248
249 if ( PROTOCOL_SSH.equals( repoUrl.getProtocol() ) ||
250 PROTOCOL_RSYNC.equals( repoUrl.getProtocol() ) ||
251 PROTOCOL_GIT.equals( repoUrl.getProtocol() ) ||
252 PROTOCOL_HTTP.equals( repoUrl.getProtocol() ) ||
253 PROTOCOL_HTTPS.equals( repoUrl.getProtocol() ) ||
254 PROTOCOL_NONE.equals( repoUrl.getProtocol() ) )
255 {
256 urlSupportsUserInformation = true;
257 }
258
259 if ( repoUrl.getProtocol() != null && repoUrl.getProtocol().length() > 0 )
260 {
261 urlSb.append( "://" );
262 }
263
264
265 if ( urlSupportsUserInformation )
266 {
267 String userName = repoUrl.getUserName();
268
269 if ( getUser() != null && getUser().length() > 0 )
270 {
271 userName = getUser();
272 }
273
274 String password = repoUrl.getPassword();
275 if ( getPassword() != null && getPassword().length() > 0 )
276 {
277 password = getPassword();
278 }
279
280 if ( userName != null && userName.length() > 0 )
281 {
282 urlSb.append( userName );
283
284 if ( password != null && password.length() > 0 )
285 {
286 urlSb.append( ':' ).append( password );
287 }
288
289 urlSb.append( '@' );
290 }
291 }
292
293
294 urlSb.append( repoUrl.getHost() );
295 if ( repoUrl.getPort() != null && repoUrl.getPort().length() > 0 )
296 {
297 urlSb.append( ':' ).append( repoUrl.getPort() );
298 }
299
300
301 urlSb.append( repoUrl.getPath() );
302
303 return urlSb.toString();
304 }
305
306
307
308
309
310
311
312
313 private String parseProtocol( RepositoryUrl repoUrl, String url )
314 throws ScmException
315 {
316
317 if ( url.startsWith( PROTOCOL_FILE + PROTOCOL_SEPARATOR ) )
318 {
319 repoUrl.setProtocol( PROTOCOL_FILE );
320 }
321 else if ( url.startsWith( PROTOCOL_HTTPS + PROTOCOL_SEPARATOR ) )
322 {
323 repoUrl.setProtocol( PROTOCOL_HTTPS );
324 }
325 else if ( url.startsWith( PROTOCOL_HTTP + PROTOCOL_SEPARATOR ) )
326 {
327 repoUrl.setProtocol( PROTOCOL_HTTP );
328 }
329 else if ( url.startsWith( PROTOCOL_SSH + PROTOCOL_SEPARATOR ) )
330 {
331 repoUrl.setProtocol( PROTOCOL_SSH );
332 }
333 else if ( url.startsWith( PROTOCOL_GIT + PROTOCOL_SEPARATOR ) )
334 {
335 repoUrl.setProtocol( PROTOCOL_GIT );
336 }
337 else if ( url.startsWith( PROTOCOL_RSYNC + PROTOCOL_SEPARATOR ) )
338 {
339 repoUrl.setProtocol( PROTOCOL_RSYNC );
340 }
341 else
342 {
343
344
345 repoUrl.setProtocol( PROTOCOL_NONE );
346 return url;
347 }
348
349 url = url.substring( repoUrl.getProtocol().length() + 3 );
350
351 return url;
352 }
353
354
355
356
357
358
359
360
361
362 private String parseUserInfo( RepositoryUrl repoUrl, String url )
363 throws ScmException
364 {
365
366 int indexAt = url.indexOf( '@' );
367 if ( indexAt >= 0 )
368 {
369 String userInfo = url.substring( 0, indexAt );
370 int indexPwdSep = userInfo.indexOf( ':' );
371 if ( indexPwdSep < 0 )
372 {
373 repoUrl.setUserName( userInfo );
374 }
375 else
376 {
377 repoUrl.setUserName( userInfo.substring( 0, indexPwdSep ) );
378 repoUrl.setPassword( userInfo.substring( indexPwdSep + 1 ) );
379 }
380
381 url = url.substring( indexAt + 1 );
382 }
383 return url;
384 }
385
386
387
388
389
390
391
392
393
394
395 private String parseHostAndPort( RepositoryUrl repoUrl, String url )
396 throws ScmException
397 {
398
399 repoUrl.setPort( "" );
400 repoUrl.setHost( "" );
401
402 if ( PROTOCOL_FILE.equals( repoUrl.getProtocol() ) )
403 {
404
405 return url;
406 }
407 else
408 {
409
410 Matcher hostAndPortMatcher = HOST_AND_PORT_EXTRACTOR.matcher( url );
411 if ( hostAndPortMatcher.matches() )
412 {
413 if ( hostAndPortMatcher.groupCount() > 1 && hostAndPortMatcher.group( 1 ) != null )
414 {
415 repoUrl.setHost( hostAndPortMatcher.group( 1 ) );
416 }
417 if ( hostAndPortMatcher.groupCount() > 2 && hostAndPortMatcher.group( 2 ) != null )
418 {
419 repoUrl.setPort( hostAndPortMatcher.group( 2 ) );
420 }
421
422 StringBuilder computedUrl = new StringBuilder();
423 if ( hostAndPortMatcher.group( hostAndPortMatcher.groupCount() - 1 ) != null )
424 {
425 computedUrl.append( hostAndPortMatcher.group( hostAndPortMatcher.groupCount() - 1 ) );
426 }
427 if ( hostAndPortMatcher.group( hostAndPortMatcher.groupCount() ) != null )
428 {
429 computedUrl.append( hostAndPortMatcher.group( hostAndPortMatcher.groupCount() ) );
430 }
431 return computedUrl.toString();
432 }
433 else
434 {
435
436 return url;
437 }
438 }
439 }
440
441
442
443
444
445 public String getRelativePath( ScmProviderRepository ancestor )
446 {
447 if ( ancestor instanceof GitScmProviderRepository )
448 {
449 GitScmProviderRepository gitAncestor = (GitScmProviderRepository) ancestor;
450
451
452 String url = getFetchUrl();
453 String path = url.replaceFirst( gitAncestor.getFetchUrl() + "/", "" );
454
455 if ( !path.equals( url ) )
456 {
457 return path;
458 }
459 }
460 return null;
461 }
462
463
464
465
466 public String toString()
467 {
468
469 if ( fetchInfo == pushInfo )
470 {
471 return getUrl( fetchInfo );
472 }
473 return URL_DELIMITER_FETCH + getUrl( fetchInfo ) +
474 URL_DELIMITER_PUSH + getUrl( pushInfo );
475 }
476
477 }