1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package javax.mail;
21
22 import java.io.ByteArrayOutputStream;
23 import java.net.MalformedURLException;
24 import java.net.URI;
25 import java.net.URISyntaxException;
26 import java.net.URL;
27
28
29
30
31 public class URLName {
32 private static final String nonEncodedChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-.*";
33
34 private String file;
35 private String host;
36 private String password;
37 private int port;
38 private String protocol;
39 private String ref;
40 private String username;
41 protected String fullURL;
42 private int hashCode;
43
44 public URLName(String url) {
45 parseString(url);
46 }
47
48 protected void parseString(String url) {
49 URI uri;
50 try {
51 if (url == null) {
52 uri = null;
53 } else {
54 uri = new URI(url);
55 }
56 } catch (URISyntaxException e) {
57 uri = null;
58 }
59 if (uri == null) {
60 protocol = null;
61 host = null;
62 port = -1;
63 file = null;
64 ref = null;
65 username = null;
66 password = null;
67 return;
68 }
69
70 protocol = checkBlank(uri.getScheme());
71 host = checkBlank(uri.getHost());
72 port = uri.getPort();
73 file = checkBlank(uri.getPath());
74
75
76
77 if (file != null && file.length() > 1 && file.startsWith("/")) {
78 file = checkBlank(file.substring(1));
79 }
80
81 ref = checkBlank(uri.getFragment());
82 String userInfo = checkBlank(uri.getUserInfo());
83 if (userInfo == null) {
84 username = null;
85 password = null;
86 } else {
87 int pos = userInfo.indexOf(':');
88 if (pos == -1) {
89 username = userInfo;
90 password = null;
91 } else {
92 username = userInfo.substring(0, pos);
93 password = userInfo.substring(pos + 1);
94 }
95 }
96 updateFullURL();
97 }
98
99 public URLName(String protocol, String host, int port, String file, String username, String password) {
100 this.protocol = checkBlank(protocol);
101 this.host = checkBlank(host);
102 this.port = port;
103 if (file == null || file.length() == 0) {
104 this.file = null;
105 ref = null;
106 } else {
107 int pos = file.indexOf('#');
108 if (pos == -1) {
109 this.file = file;
110 ref = null;
111 } else {
112 this.file = file.substring(0, pos);
113 ref = file.substring(pos + 1);
114 }
115 }
116 this.username = checkBlank(username);
117 if (this.username != null) {
118 this.password = checkBlank(password);
119 } else {
120 this.password = null;
121 }
122 username = encode(username);
123 password = encode(password);
124 updateFullURL();
125 }
126
127 public URLName(URL url) {
128 protocol = checkBlank(url.getProtocol());
129 host = checkBlank(url.getHost());
130 port = url.getPort();
131 file = checkBlank(url.getFile());
132 ref = checkBlank(url.getRef());
133 String userInfo = checkBlank(url.getUserInfo());
134 if (userInfo == null) {
135 username = null;
136 password = null;
137 } else {
138 int pos = userInfo.indexOf(':');
139 if (pos == -1) {
140 username = userInfo;
141 password = null;
142 } else {
143 username = userInfo.substring(0, pos);
144 password = userInfo.substring(pos + 1);
145 }
146 }
147 updateFullURL();
148 }
149
150 private static String checkBlank(String target) {
151 if (target == null || target.length() == 0) {
152 return null;
153 } else {
154 return target;
155 }
156 }
157
158 private void updateFullURL() {
159 hashCode = 0;
160 StringBuffer buf = new StringBuffer(100);
161 if (protocol != null) {
162 buf.append(protocol).append(':');
163 if (host != null) {
164 buf.append("//");
165 if (username != null) {
166 buf.append(encode(username));
167 if (password != null) {
168 buf.append(':').append(encode(password));
169 }
170 buf.append('@');
171 }
172 buf.append(host);
173 if (port != -1) {
174 buf.append(':').append(port);
175 }
176 if (file != null) {
177 buf.append('/').append(file);
178 }
179 hashCode = buf.toString().hashCode();
180 if (ref != null) {
181 buf.append('#').append(ref);
182 }
183 }
184 }
185 fullURL = buf.toString();
186 }
187
188 public boolean equals(Object o) {
189 if (o instanceof URLName == false) {
190 return false;
191 }
192 URLName other = (URLName) o;
193
194 if (protocol == null || other.protocol == null || !protocol.equals(other.protocol)) {
195 return false;
196 }
197
198 if (port != other.port) {
199 return false;
200 }
201
202
203 return areSame(host, other.host) && areSame(file, other.file) && areSame(username, other.username) && areSame(password, other.password);
204 }
205
206 private static boolean areSame(String s1, String s2) {
207 if (s1 == null) {
208 return s2 == null;
209 } else {
210 return s1.equals(s2);
211 }
212 }
213
214 public int hashCode() {
215 return hashCode;
216 }
217
218 public String toString() {
219 return fullURL;
220 }
221
222 public String getFile() {
223 return file;
224 }
225
226 public String getHost() {
227 return host;
228 }
229
230 public String getPassword() {
231 return password;
232 }
233
234 public int getPort() {
235 return port;
236 }
237
238 public String getProtocol() {
239 return protocol;
240 }
241
242 public String getRef() {
243 return ref;
244 }
245
246 public URL getURL() throws MalformedURLException {
247 return new URL(fullURL);
248 }
249
250 public String getUsername() {
251 return username;
252 }
253
254
255
256
257
258
259
260
261
262 private static String encode(String v) {
263
264 if (v == null) {
265 return null;
266 }
267 boolean needsEncoding = false;
268 for (int i = 0; i < v.length(); i++) {
269
270 if (nonEncodedChars.indexOf(v.charAt(i)) == -1) {
271
272 needsEncoding = true;
273 break;
274 }
275 }
276
277 if (!needsEncoding) {
278 return v;
279 }
280
281
282
283 StringBuffer encoded = new StringBuffer(v.length() + 10);
284
285
286
287 byte[] data = v.getBytes();
288
289 for (int i = 0; i < data.length; i++) {
290
291
292 char ch = (char)(data[i] & 0xff);
293
294 if (ch == ' ') {
295 encoded.append('+');
296 }
297
298 else if (nonEncodedChars.indexOf(ch) == -1) {
299
300
301 char firstChar = Character.toUpperCase(Character.forDigit((ch >> 4) & 0xf, 16));
302 char secondChar = Character.toUpperCase(Character.forDigit(ch & 0xf, 16));
303
304
305 encoded.append('%');
306 encoded.append(firstChar);
307 encoded.append(secondChar);
308 }
309 else {
310
311 encoded.append(ch);
312 }
313 }
314
315 return encoded.toString();
316 }
317 }