233 throw new IllegalArgumentException("Invalid port number :" + 234 port); 235 start = i; 236 // If the authority is defined then the path is defined by the 237 // spec only; See RFC 2396 Section 5.2.4. 238 if (authority != null && authority.length() > 0) 239 path = ""; 240 } 241 242 if (host == null) { 243 host = ""; 244 } 245 246 // Parse the file path if any 247 if (start < limit) { 248 if (spec.charAt(start) == '/') { 249 path = spec.substring(start, limit); 250 } else if (path != null && path.length() > 0) { 251 isRelPath = true; 252 int ind = path.lastIndexOf('/'); 253 String seperator = ""; 254 if (ind == -1 && authority != null) 255 seperator = "/"; 256 path = path.substring(0, ind + 1) + seperator + 257 spec.substring(start, limit); 258 259 } else { 260 String seperator = (authority != null) ? "/" : ""; 261 path = seperator + spec.substring(start, limit); 262 } 263 } else if (queryOnly && path != null) { 264 int ind = path.lastIndexOf('/'); 265 if (ind < 0) 266 ind = 0; 267 path = path.substring(0, ind) + "/"; 268 } 269 if (path == null) 270 path = ""; 271 272 if (isRelPath) { 273 // Remove embedded /./ 274 while ((i = path.indexOf("/./")) >= 0) { 275 path = path.substring(0, i) + path.substring(i + 2); 276 } 277 // Remove embedded /../ if possible 278 i = 0; 279 while ((i = path.indexOf("/../", i)) >= 0) { 280 /* 281 * A "/../" will cancel the previous segment and itself, 297 if ((limit = path.lastIndexOf('/', i - 1)) >= 0) { 298 path = path.substring(0, limit+1); 299 } else { 300 break; 301 } 302 } 303 // Remove starting . 304 if (path.startsWith("./") && path.length() > 2) 305 path = path.substring(2); 306 307 // Remove trailing . 308 if (path.endsWith("/.")) 309 path = path.substring(0, path.length() -1); 310 } 311 312 setURL(u, protocol, host, port, authority, userInfo, path, query, ref); 313 } 314 315 /** 316 * Returns the default port for a URL parsed by this handler. This method 317 * is meant to be overidden by handlers with default port numbers. 318 * @return the default port for a {@code URL} parsed by this handler. 319 * @since 1.3 320 */ 321 protected int getDefaultPort() { 322 return -1; 323 } 324 325 /** 326 * Provides the default equals calculation. May be overidden by handlers 327 * for other protocols that have different requirements for equals(). 328 * This method requires that none of its arguments is null. This is 329 * guaranteed by the fact that it is only called by java.net.URL class. 330 * @param u1 a URL object 331 * @param u2 a URL object 332 * @return {@code true} if the two urls are 333 * considered equal, ie. they refer to the same 334 * fragment in the same file. 335 * @since 1.3 336 */ 337 protected boolean equals(URL u1, URL u2) { 338 String ref1 = u1.getRef(); 339 String ref2 = u2.getRef(); 340 return (ref1 == ref2 || (ref1 != null && ref1.equals(ref2))) && 341 sameFile(u1, u2); 342 } 343 344 /** 345 * Provides the default hash calculation. May be overidden by handlers for 346 * other protocols that have different requirements for hashCode 347 * calculation. 348 * @param u a URL object 349 * @return an {@code int} suitable for hash table indexing 350 * @since 1.3 351 */ 352 protected int hashCode(URL u) { 353 int h = 0; 354 355 // Generate the protocol part. 356 String protocol = u.getProtocol(); 357 if (protocol != null) 358 h += protocol.hashCode(); 359 360 // Generate the host part. 361 InetAddress addr = getHostAddress(u); 362 if (addr != null) { 363 h += addr.hashCode(); 364 } else { 365 String host = u.getHost(); | 233 throw new IllegalArgumentException("Invalid port number :" + 234 port); 235 start = i; 236 // If the authority is defined then the path is defined by the 237 // spec only; See RFC 2396 Section 5.2.4. 238 if (authority != null && authority.length() > 0) 239 path = ""; 240 } 241 242 if (host == null) { 243 host = ""; 244 } 245 246 // Parse the file path if any 247 if (start < limit) { 248 if (spec.charAt(start) == '/') { 249 path = spec.substring(start, limit); 250 } else if (path != null && path.length() > 0) { 251 isRelPath = true; 252 int ind = path.lastIndexOf('/'); 253 String separator = ""; 254 if (ind == -1 && authority != null) 255 separator = "/"; 256 path = path.substring(0, ind + 1) + separator + 257 spec.substring(start, limit); 258 259 } else { 260 String separator = (authority != null) ? "/" : ""; 261 path = separator + spec.substring(start, limit); 262 } 263 } else if (queryOnly && path != null) { 264 int ind = path.lastIndexOf('/'); 265 if (ind < 0) 266 ind = 0; 267 path = path.substring(0, ind) + "/"; 268 } 269 if (path == null) 270 path = ""; 271 272 if (isRelPath) { 273 // Remove embedded /./ 274 while ((i = path.indexOf("/./")) >= 0) { 275 path = path.substring(0, i) + path.substring(i + 2); 276 } 277 // Remove embedded /../ if possible 278 i = 0; 279 while ((i = path.indexOf("/../", i)) >= 0) { 280 /* 281 * A "/../" will cancel the previous segment and itself, 297 if ((limit = path.lastIndexOf('/', i - 1)) >= 0) { 298 path = path.substring(0, limit+1); 299 } else { 300 break; 301 } 302 } 303 // Remove starting . 304 if (path.startsWith("./") && path.length() > 2) 305 path = path.substring(2); 306 307 // Remove trailing . 308 if (path.endsWith("/.")) 309 path = path.substring(0, path.length() -1); 310 } 311 312 setURL(u, protocol, host, port, authority, userInfo, path, query, ref); 313 } 314 315 /** 316 * Returns the default port for a URL parsed by this handler. This method 317 * is meant to be overridden by handlers with default port numbers. 318 * @return the default port for a {@code URL} parsed by this handler. 319 * @since 1.3 320 */ 321 protected int getDefaultPort() { 322 return -1; 323 } 324 325 /** 326 * Provides the default equals calculation. May be overridden by handlers 327 * for other protocols that have different requirements for equals(). 328 * This method requires that none of its arguments is null. This is 329 * guaranteed by the fact that it is only called by java.net.URL class. 330 * @param u1 a URL object 331 * @param u2 a URL object 332 * @return {@code true} if the two urls are 333 * considered equal, ie. they refer to the same 334 * fragment in the same file. 335 * @since 1.3 336 */ 337 protected boolean equals(URL u1, URL u2) { 338 String ref1 = u1.getRef(); 339 String ref2 = u2.getRef(); 340 return (ref1 == ref2 || (ref1 != null && ref1.equals(ref2))) && 341 sameFile(u1, u2); 342 } 343 344 /** 345 * Provides the default hash calculation. May be overridden by handlers for 346 * other protocols that have different requirements for hashCode 347 * calculation. 348 * @param u a URL object 349 * @return an {@code int} suitable for hash table indexing 350 * @since 1.3 351 */ 352 protected int hashCode(URL u) { 353 int h = 0; 354 355 // Generate the protocol part. 356 String protocol = u.getProtocol(); 357 if (protocol != null) 358 h += protocol.hashCode(); 359 360 // Generate the host part. 361 InetAddress addr = getHostAddress(u); 362 if (addr != null) { 363 h += addr.hashCode(); 364 } else { 365 String host = u.getHost(); |