/** * Creates a <code>URL</code> object from the specified <code>protocol</code>, <code>host</code>, * <code>port</code> number, <code>file</code>, and <code>handler</code>. Specifying a <code>port * </code> number of <code>-1</code> indicates that the URL should use the default port for the * protocol. Specifying a <code>handler</code> of <code>null</code> indicates that the URL should * use a default stream handler for the protocol, as outlined for: * java.net.URL#URL(java.lang.String, java.lang.String, int, java.lang.String) * * <p>If the handler is not null and there is a security manager, the security manager's <code> * checkPermission</code> method is called with a <code>NetPermission("specifyStreamHandler") * </code> permission. This may result in a SecurityException. * * <p>No validation of the inputs is performed by this constructor. * * @param protocol the name of the protocol to use. * @param host the name of the host. * @param port the port number on the host. * @param file the file on the host * @param handler the stream handler for the URL. * @exception MalformedURLException if an unknown protocol is specified. * @exception SecurityException if a security manager exists and its <code>checkPermission</code> * method doesn't allow specifying a stream handler explicitly. * @see java.lang.System#getProperty(java.lang.String) * @see java.net.URL#setURLStreamHandlerFactory( java.net.URLStreamHandlerFactory) * @see java.net.URLStreamHandler * @see java.net.URLStreamHandlerFactory#createURLStreamHandler( java.lang.String) * @see SecurityManager#checkPermission * @see java.net.NetPermission */ public URL(String protocol, String host, int port, String file, URLStreamHandler handler) throws MalformedURLException { if (handler != null) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { // check for permission to specify a handler checkSpecifyHandler(sm); } } protocol = protocol.toLowerCase(); this.protocol = protocol; if (host != null) { /** if host is a literal IPv6 address, we will make it conform to RFC 2732 */ if (host.indexOf(':') >= 0 && !host.startsWith("[")) { host = "[" + host + "]"; } this.host = host; if (port < -1) { throw new MalformedURLException("Invalid port number :" + port); } this.port = port; authority = (port == -1) ? host : host + ":" + port; } Parts parts = new Parts(file); path = parts.getPath(); query = parts.getQuery(); if (query != null) { this.file = path + "?" + query; } else { this.file = path; } ref = parts.getRef(); // Note: we don't do validation of the URL here. Too risky to change // right now, but worth considering for future reference. -br if (handler == null && (handler = getURLStreamHandler(protocol)) == null) { throw new MalformedURLException("unknown protocol: " + protocol); } this.handler = handler; }
/** * Creates a URL by parsing the given spec with the specified handler within a specified context. * If the handler is null, the parsing occurs as with the two argument constructor. * * @param context the context in which to parse the specification. * @param spec the <code>String</code> to parse as a URL. * @param handler the stream handler for the URL. * @exception MalformedURLException if no protocol is specified, or an unknown protocol is found, * or <tt>spec</tt> is <tt>null</tt>. * @exception SecurityException if a security manager exists and its <code>checkPermission</code> * method doesn't allow specifying a stream handler. * @see java.net.URL#URL(java.lang.String, java.lang.String, int, java.lang.String) * @see java.net.URLStreamHandler * @see java.net.URLStreamHandler#parseURL(java.net.URL, java.lang.String, int, int) */ public URL(URL context, String spec, URLStreamHandler handler) throws MalformedURLException { String original = spec; int i, limit, c; int start = 0; String newProtocol = null; boolean aRef = false; boolean isRelative = false; // Check for permission to specify a handler if (handler != null) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkSpecifyHandler(sm); } } try { limit = spec.length(); while ((limit > 0) && (spec.charAt(limit - 1) <= ' ')) { limit--; // eliminate trailing whitespace } while ((start < limit) && (spec.charAt(start) <= ' ')) { start++; // eliminate leading whitespace } if (spec.regionMatches(true, start, "url:", 0, 4)) { start += 4; } if (start < spec.length() && spec.charAt(start) == '#') { /* we're assuming this is a ref relative to the context URL. * This means protocols cannot start w/ '#', but we must parse * ref URL's like: "hello:there" w/ a ':' in them. */ aRef = true; } for (i = start; !aRef && (i < limit) && ((c = spec.charAt(i)) != '/'); i++) { if (c == ':') { String s = spec.substring(start, i).toLowerCase(); if (isValidProtocol(s)) { newProtocol = s; start = i + 1; } break; } } // Only use our context if the protocols match. protocol = newProtocol; if ((context != null) && ((newProtocol == null) || newProtocol.equalsIgnoreCase(context.protocol))) { // inherit the protocol handler from the context // if not specified to the constructor if (handler == null) { handler = context.handler; } // If the context is a hierarchical URL scheme and the spec // contains a matching scheme then maintain backwards // compatibility and treat it as if the spec didn't contain // the scheme; see 5.2.3 of RFC2396 if (context.path != null && context.path.startsWith("/")) newProtocol = null; if (newProtocol == null) { protocol = context.protocol; authority = context.authority; userInfo = context.userInfo; host = context.host; port = context.port; file = context.file; path = context.path; isRelative = true; } } if (protocol == null) { throw new MalformedURLException("no protocol: " + original); } // Get the protocol handler if not specified or the protocol // of the context could not be used if (handler == null && (handler = getURLStreamHandler(protocol)) == null) { throw new MalformedURLException("unknown protocol: " + protocol); } this.handler = handler; i = spec.indexOf('#', start); if (i >= 0) { ref = spec.substring(i + 1, limit); limit = i; } /* * Handle special case inheritance of query and fragment * implied by RFC2396 section 5.2.2. */ if (isRelative && start == limit) { query = context.query; if (ref == null) { ref = context.ref; } } handler.parseURL(this, spec, start, limit); } catch (MalformedURLException e) { throw e; } catch (Exception e) { MalformedURLException exception = new MalformedURLException(e.getMessage()); exception.initCause(e); throw exception; } }