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