1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.eclipse.aether.transport.file;
20
21 /**
22 * URL handling for file URLs. Based on org.apache.maven.wagon.PathUtils.
23 */
24 final class PathUtils {
25
26 private PathUtils() {}
27
28 /**
29 * Return the protocol name. <br/>
30 * E.g: for input <code>http://www.codehause.org</code> this method will return <code>http</code>
31 *
32 * @param url the url
33 * @return the host name
34 */
35 public static String protocol(final String url) {
36 final int pos = url.indexOf(":");
37
38 if (pos == -1) {
39 return "";
40 }
41 return url.substring(0, pos).trim();
42 }
43
44 /**
45 * Derive the path portion of the given URL.
46 *
47 * @param url the file-repository URL
48 * @return the basedir of the repository
49 */
50 public static String basedir(String url) {
51 String protocol = PathUtils.protocol(url);
52
53 String retValue = null;
54
55 if (protocol.length() > 0) {
56 retValue = url.substring(protocol.length() + 1);
57 } else {
58 retValue = url;
59 }
60 retValue = decode(retValue);
61 // special case: if omitted // on protocol, keep path as is
62 if (retValue.startsWith("//")) {
63 retValue = retValue.substring(2);
64
65 if (retValue.length() >= 2 && (retValue.charAt(1) == '|' || retValue.charAt(1) == ':')) {
66 // special case: if there is a windows drive letter, then keep the original return value
67 retValue = retValue.charAt(0) + ":" + retValue.substring(2);
68 } else {
69 // Now we expect the host
70 int index = retValue.indexOf("/");
71 if (index >= 0) {
72 retValue = retValue.substring(index + 1);
73 }
74
75 // special case: if there is a windows drive letter, then keep the original return value
76 if (retValue.length() >= 2 && (retValue.charAt(1) == '|' || retValue.charAt(1) == ':')) {
77 retValue = retValue.charAt(0) + ":" + retValue.substring(2);
78 } else if (index >= 0) {
79 // leading / was previously stripped
80 retValue = "/" + retValue;
81 }
82 }
83 }
84
85 // special case: if there is a windows drive letter using |, switch to :
86 if (retValue.length() >= 2 && retValue.charAt(1) == '|') {
87 retValue = retValue.charAt(0) + ":" + retValue.substring(2);
88 }
89
90 return retValue.trim();
91 }
92
93 /**
94 * Decodes the specified (portion of a) URL. <strong>Note:</strong> This decoder assumes that ISO-8859-1 is used to
95 * convert URL-encoded octets to characters.
96 *
97 * @param url The URL to decode, may be <code>null</code>.
98 * @return The decoded URL or <code>null</code> if the input was <code>null</code>.
99 */
100 static String decode(String url) {
101 String decoded = url;
102 if (url != null) {
103 int pos = -1;
104 while ((pos = decoded.indexOf('%', pos + 1)) >= 0) {
105 if (pos + 2 < decoded.length()) {
106 String hexStr = decoded.substring(pos + 1, pos + 3);
107 char ch = (char) Integer.parseInt(hexStr, 16);
108 decoded = decoded.substring(0, pos) + ch + decoded.substring(pos + 3);
109 }
110 }
111 }
112 return decoded;
113 }
114 }