2 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
19 * - Neither the name of the Git Development Community nor the
20 * names of its contributors may be used to endorse or promote
21 * products derived from this software without specific prior
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
25 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
26 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 package org
.spearce
.jgit
.transport
;
41 import java
.net
.URISyntaxException
;
42 import java
.util
.regex
.Matcher
;
43 import java
.util
.regex
.Pattern
;
46 * This URI like construct used for referencing Git archives over the net, as
47 * well as locally stored archives. The most important difference compared to
48 * RFC 2396 URI's is that no URI encoding/decoding ever takes place. A space or
49 * any special character is written as-is.
52 private static final Pattern FULL_URI
= Pattern
53 .compile("^(?:([a-z+]+)://(?:([^/]+?)(?::([^/]+?))?@)?(?:([^/]+?))?(?::(\\d+))?)?((?:[A-Za-z]:)?/.+)$");
55 private static final Pattern SCP_URI
= Pattern
56 .compile("^(?:([^@]+?)@)?([^:]+?):(.+)$");
58 private String scheme
;
66 private int port
= -1;
71 * Parse and construct an {@link URIish} from a string
74 * @throws URISyntaxException
76 public URIish(String s
) throws URISyntaxException
{
77 Matcher matcher
= FULL_URI
.matcher(s
);
78 if (matcher
.matches()) {
79 scheme
= matcher
.group(1);
80 user
= matcher
.group(2);
81 pass
= matcher
.group(3);
82 host
= matcher
.group(4);
83 if (matcher
.group(5) != null)
84 port
= Integer
.parseInt(matcher
.group(5));
85 path
= matcher
.group(6);
86 if (path
.length() >= 3
87 && path
.charAt(0) == '/'
88 && path
.charAt(2) == ':'
89 && (path
.charAt(1) >= 'A' && path
.charAt(1) <= 'Z'
90 || path
.charAt(1) >= 'a' && path
.charAt(1) <= 'z'))
91 path
= path
.substring(1);
93 matcher
= SCP_URI
.matcher(s
);
94 if (matcher
.matches()) {
95 user
= matcher
.group(1);
96 host
= matcher
.group(2);
97 path
= matcher
.group(3);
99 throw new URISyntaxException(s
, "Cannot parse Git URI-ish");
103 /** Create an empty, non-configured URI. */
105 // Configure nothing.
108 private URIish(final URIish u
) {
109 this.scheme
= u
.scheme
;
118 * @return true if this URI references a repository on another system.
120 public boolean isRemote() {
121 return getHost() != null;
125 * @return host name part or null
127 public String
getHost() {
132 * Return a new URI matching this one, but with a different host.
135 * the new value for host.
136 * @return a new URI with the updated value.
138 public URIish
setHost(final String n
) {
139 final URIish r
= new URIish(this);
145 * @return protocol name or null for local references
147 public String
getScheme() {
152 * Return a new URI matching this one, but with a different scheme.
155 * the new value for scheme.
156 * @return a new URI with the updated value.
158 public URIish
setScheme(final String n
) {
159 final URIish r
= new URIish(this);
165 * @return path name component
167 public String
getPath() {
172 * Return a new URI matching this one, but with a different path.
175 * the new value for path.
176 * @return a new URI with the updated value.
178 public URIish
setPath(final String n
) {
179 final URIish r
= new URIish(this);
185 * @return user name requested for transfer or null
187 public String
getUser() {
192 * Return a new URI matching this one, but with a different user.
195 * the new value for user.
196 * @return a new URI with the updated value.
198 public URIish
setUser(final String n
) {
199 final URIish r
= new URIish(this);
205 * @return password requested for transfer or null
207 public String
getPass() {
212 * Return a new URI matching this one, but with a different password.
215 * the new value for password.
216 * @return a new URI with the updated value.
218 public URIish
setPass(final String n
) {
219 final URIish r
= new URIish(this);
225 * @return port number requested for transfer or -1 if not explicit
227 public int getPort() {
232 * Return a new URI matching this one, but with a different port.
235 * the new value for port.
236 * @return a new URI with the updated value.
238 public URIish
setPort(final int n
) {
239 final URIish r
= new URIish(this);
240 r
.port
= n
> 0 ? n
: -1;
244 public int hashCode() {
246 if (getScheme() != null)
247 hc
= hc
* 31 + getScheme().hashCode();
248 if (getUser() != null)
249 hc
= hc
* 31 + getUser().hashCode();
250 if (getPass() != null)
251 hc
= hc
* 31 + getPass().hashCode();
252 if (getHost() != null)
253 hc
= hc
* 31 + getHost().hashCode();
255 hc
= hc
* 31 + getPort();
256 if (getPath() != null)
257 hc
= hc
* 31 + getPath().hashCode();
261 public boolean equals(final Object obj
) {
262 if (!(obj
instanceof URIish
))
264 final URIish b
= (URIish
) obj
;
265 if (!eq(getScheme(), b
.getScheme()))
267 if (!eq(getUser(), b
.getUser()))
269 if (!eq(getPass(), b
.getPass()))
271 if (!eq(getHost(), b
.getHost()))
273 if (getPort() != b
.getPort())
275 if (!eq(getPath(), b
.getPath()))
280 private static boolean eq(final String a
, final String b
) {
283 if (a
== null || b
== null)
288 public String
toString() {
289 final StringBuilder r
= new StringBuilder();
290 if (getScheme() != null) {
291 r
.append(getScheme());
295 if (getUser() != null) {
297 if (getPass() != null) {
303 if (getHost() != null) {
304 if (getUser() != null)
307 if (getScheme() != null && getPort() > 0) {
313 if (getPath() != null) {
314 if (getScheme() != null) {
315 if (!getPath().startsWith("/"))
317 } else if (getHost() != null)