1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.scm.provider.git.repository;
20
21 import java.net.URI;
22 import java.net.URISyntaxException;
23 import java.util.regex.Matcher;
24 import java.util.regex.Pattern;
25
26 import org.apache.maven.scm.ScmException;
27 import org.apache.maven.scm.provider.ScmProviderRepository;
28 import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
29 import org.apache.maven.scm.provider.git.util.GitUtil;
30
31
32
33
34
35
36 public class GitScmProviderRepository extends ScmProviderRepositoryWithHost {
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) throws ScmException {
109 if (url == null) {
110 throw new ScmException("url must not be null");
111 }
112
113 if (url.startsWith(URL_DELIMITER_FETCH)) {
114 String fetch = url.substring(URL_DELIMITER_FETCH.length());
115
116 int indexPushDelimiter = fetch.indexOf(URL_DELIMITER_PUSH);
117 if (indexPushDelimiter >= 0) {
118 String push = fetch.substring(indexPushDelimiter + URL_DELIMITER_PUSH.length());
119 pushInfo = parseUrl(push);
120
121 fetch = fetch.substring(0, indexPushDelimiter);
122 }
123
124 fetchInfo = parseUrl(fetch);
125
126 if (pushInfo == null) {
127 pushInfo = fetchInfo;
128 }
129 } else if (url.startsWith(URL_DELIMITER_PUSH)) {
130 String push = url.substring(URL_DELIMITER_PUSH.length());
131
132 int indexFetchDelimiter = push.indexOf(URL_DELIMITER_FETCH);
133 if (indexFetchDelimiter >= 0) {
134 String fetch = push.substring(indexFetchDelimiter + URL_DELIMITER_FETCH.length());
135 fetchInfo = parseUrl(fetch);
136
137 push = push.substring(0, indexFetchDelimiter);
138 }
139
140 pushInfo = parseUrl(push);
141
142 if (fetchInfo == null) {
143 fetchInfo = pushInfo;
144 }
145 } else {
146 fetchInfo = pushInfo = parseUrl(url);
147 }
148
149
150
151 setUser(pushInfo.getUserName());
152 setPassword(pushInfo.getPassword());
153 setHost(pushInfo.getHost());
154 if (pushInfo.getPort() != null && pushInfo.getPort().length() > 0) {
155 setPort(Integer.parseInt(pushInfo.getPort()));
156 }
157 }
158
159 public GitScmProviderRepository(String url, String user, String password) throws ScmException {
160 this(url);
161
162 setUser(user);
163
164 setPassword(password);
165 }
166
167
168
169
170 public String getProvider() {
171 return provider;
172 }
173
174 public RepositoryUrl getFetchInfo() {
175 return fetchInfo;
176 }
177
178 public RepositoryUrl getPushInfo() {
179 return pushInfo;
180 }
181
182
183
184
185 public String getFetchUrl() {
186 return getUrl(fetchInfo);
187 }
188
189
190
191
192 public String getFetchUrlWithMaskedPassword() {
193 return GitUtil.maskPasswordInUrl(getFetchUrl());
194 }
195
196
197
198
199 public String getPushUrl() {
200 return getUrl(pushInfo);
201 }
202
203
204
205
206 public String getPushUrlWithMaskedPassword() {
207 return GitUtil.maskPasswordInUrl(getPushUrl());
208 }
209
210
211
212
213
214
215
216
217
218 private RepositoryUrl parseUrl(String url) throws ScmException {
219 RepositoryUrl repoUrl = new RepositoryUrl();
220
221 url = parseProtocol(repoUrl, url);
222 url = parseUserInfo(repoUrl, url);
223 url = parseHostAndPort(repoUrl, url);
224
225 repoUrl.setPath(url);
226 return repoUrl;
227 }
228
229
230
231
232
233 private String getUrl(RepositoryUrl repoUrl) {
234 StringBuilder urlSb = new StringBuilder(repoUrl.getProtocol());
235 boolean urlSupportsUserInformation = false;
236
237 if (PROTOCOL_SSH.equals(repoUrl.getProtocol())
238 || PROTOCOL_RSYNC.equals(repoUrl.getProtocol())
239 || PROTOCOL_GIT.equals(repoUrl.getProtocol())
240 || PROTOCOL_HTTP.equals(repoUrl.getProtocol())
241 || PROTOCOL_HTTPS.equals(repoUrl.getProtocol())
242 || PROTOCOL_NONE.equals(repoUrl.getProtocol())) {
243 urlSupportsUserInformation = true;
244 }
245
246 if (repoUrl.getProtocol() != null && repoUrl.getProtocol().length() > 0) {
247 urlSb.append("://");
248 }
249
250
251 if (urlSupportsUserInformation) {
252 String userName = repoUrl.getUserName();
253
254 if (getUser() != null && getUser().length() > 0) {
255 userName = getUser();
256 }
257
258 String password = repoUrl.getPassword();
259 if (getPassword() != null && getPassword().length() > 0) {
260 password = getPassword();
261 }
262
263 if (userName != null && userName.length() > 0) {
264 String userInfo = userName;
265 if (password != null && password.length() > 0) {
266 userInfo += ":" + password;
267 }
268
269 try {
270 URI uri = new URI(null, userInfo, "localhost", -1, null, null, null);
271 urlSb.append(uri.getRawUserInfo());
272 } catch (URISyntaxException e) {
273
274
275 e.printStackTrace();
276 }
277
278 urlSb.append('@');
279 }
280 }
281
282
283 urlSb.append(repoUrl.getHost());
284 if (repoUrl.getPort() != null && repoUrl.getPort().length() > 0) {
285 urlSb.append(':').append(repoUrl.getPort());
286 }
287
288
289 urlSb.append(repoUrl.getPath());
290
291 return urlSb.toString();
292 }
293
294
295
296
297
298
299
300
301 private String parseProtocol(RepositoryUrl repoUrl, String url) throws ScmException {
302
303 if (url.startsWith(PROTOCOL_FILE + PROTOCOL_SEPARATOR)) {
304 repoUrl.setProtocol(PROTOCOL_FILE);
305 } else if (url.startsWith(PROTOCOL_HTTPS + PROTOCOL_SEPARATOR)) {
306 repoUrl.setProtocol(PROTOCOL_HTTPS);
307 } else if (url.startsWith(PROTOCOL_HTTP + PROTOCOL_SEPARATOR)) {
308 repoUrl.setProtocol(PROTOCOL_HTTP);
309 } else if (url.startsWith(PROTOCOL_SSH + PROTOCOL_SEPARATOR)) {
310 repoUrl.setProtocol(PROTOCOL_SSH);
311 } else if (url.startsWith(PROTOCOL_GIT + PROTOCOL_SEPARATOR)) {
312 repoUrl.setProtocol(PROTOCOL_GIT);
313 } else if (url.startsWith(PROTOCOL_RSYNC + PROTOCOL_SEPARATOR)) {
314 repoUrl.setProtocol(PROTOCOL_RSYNC);
315 } else {
316
317
318 repoUrl.setProtocol(PROTOCOL_NONE);
319 return url;
320 }
321
322 url = url.substring(repoUrl.getProtocol().length() + 3);
323
324 return url;
325 }
326
327
328
329
330
331
332
333
334
335 private String parseUserInfo(RepositoryUrl repoUrl, String url) throws ScmException {
336 if (PROTOCOL_FILE.equals(repoUrl.getProtocol())) {
337
338 return url;
339 }
340
341 int indexAt = url.lastIndexOf('@');
342 if (indexAt >= 0) {
343 String userInfo = url.substring(0, indexAt);
344 int indexPwdSep = userInfo.indexOf(':');
345 if (indexPwdSep < 0) {
346 repoUrl.setUserName(userInfo);
347 } else {
348 repoUrl.setUserName(userInfo.substring(0, indexPwdSep));
349 repoUrl.setPassword(userInfo.substring(indexPwdSep + 1));
350 }
351
352 url = url.substring(indexAt + 1);
353 }
354 return url;
355 }
356
357
358
359
360
361
362
363
364
365
366 private String parseHostAndPort(RepositoryUrl repoUrl, String url) throws ScmException {
367
368 repoUrl.setPort("");
369 repoUrl.setHost("");
370
371 if (PROTOCOL_FILE.equals(repoUrl.getProtocol())) {
372
373 return url;
374 } else {
375
376 Matcher hostAndPortMatcher = HOST_AND_PORT_EXTRACTOR.matcher(url);
377 if (hostAndPortMatcher.matches()) {
378 if (hostAndPortMatcher.groupCount() > 1 && hostAndPortMatcher.group(1) != null) {
379 repoUrl.setHost(hostAndPortMatcher.group(1));
380 }
381 if (hostAndPortMatcher.groupCount() > 2 && hostAndPortMatcher.group(2) != null) {
382 repoUrl.setPort(hostAndPortMatcher.group(2));
383 }
384
385 StringBuilder computedUrl = new StringBuilder();
386 if (hostAndPortMatcher.group(hostAndPortMatcher.groupCount() - 1) != null) {
387 computedUrl.append(hostAndPortMatcher.group(hostAndPortMatcher.groupCount() - 1));
388 }
389 if (hostAndPortMatcher.group(hostAndPortMatcher.groupCount()) != null) {
390 computedUrl.append(hostAndPortMatcher.group(hostAndPortMatcher.groupCount()));
391 }
392 return computedUrl.toString();
393 } else {
394
395 return url;
396 }
397 }
398 }
399
400
401
402
403 @Override
404 public String getRelativePath(ScmProviderRepository ancestor) {
405 if (ancestor instanceof GitScmProviderRepository) {
406 GitScmProviderRepository gitAncestor = (GitScmProviderRepository) ancestor;
407
408
409 String url = getFetchUrl();
410 String path = url.replaceFirst(gitAncestor.getFetchUrl() + "/", "");
411
412 if (!path.equals(url)) {
413 return path;
414 }
415 }
416 return null;
417 }
418
419
420
421
422 @Override
423 public String toString() {
424
425 if (fetchInfo == pushInfo) {
426 return getFetchUrlWithMaskedPassword();
427 }
428 return URL_DELIMITER_FETCH
429 + getFetchUrlWithMaskedPassword()
430 + URL_DELIMITER_PUSH
431 + getPushUrlWithMaskedPassword();
432 }
433 }